no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / netwerk / ipc / NeckoParent.cpp
blob727aea4660fb0dcc70e46a36378addb26e31a583
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/ContentPrincipal.h"
11 #include "mozilla/ipc/IPCStreamUtils.h"
12 #include "mozilla/net/ExtensionProtocolHandler.h"
13 #include "mozilla/net/PageThumbProtocolHandler.h"
14 #include "mozilla/net/NeckoParent.h"
15 #include "mozilla/net/HttpChannelParent.h"
16 #include "mozilla/net/CookieServiceParent.h"
17 #include "mozilla/net/WebSocketChannelParent.h"
18 #include "mozilla/net/WebSocketEventListenerParent.h"
19 #include "mozilla/net/DataChannelParent.h"
20 #ifdef MOZ_WIDGET_GTK
21 # include "mozilla/net/GIOChannelParent.h"
22 #endif
23 #include "mozilla/net/DocumentChannelParent.h"
24 #include "mozilla/net/SimpleChannelParent.h"
25 #include "mozilla/net/AltDataOutputStreamParent.h"
26 #include "mozilla/Unused.h"
27 #include "mozilla/net/FileChannelParent.h"
28 #include "mozilla/net/DNSRequestParent.h"
29 #include "mozilla/net/IPCTransportProvider.h"
30 #include "mozilla/net/RemoteStreamGetter.h"
31 #include "mozilla/net/RequestContextService.h"
32 #include "mozilla/net/SocketProcessParent.h"
33 #include "mozilla/net/PSocketProcessBridgeParent.h"
34 #ifdef MOZ_WEBRTC
35 # include "mozilla/net/StunAddrsRequestParent.h"
36 # include "mozilla/net/WebrtcTCPSocketParent.h"
37 #endif
38 #include "mozilla/dom/ContentParent.h"
39 #include "mozilla/dom/BrowserParent.h"
40 #include "mozilla/dom/MaybeDiscarded.h"
41 #include "mozilla/dom/network/TCPSocketParent.h"
42 #include "mozilla/dom/network/TCPServerSocketParent.h"
43 #include "mozilla/dom/network/UDPSocketParent.h"
44 #ifdef MOZ_PLACES
45 # include "mozilla/places/PageIconProtocolHandler.h"
46 #endif
47 #include "mozilla/LoadContext.h"
48 #include "mozilla/MozPromise.h"
49 #include "nsPrintfCString.h"
50 #include "mozilla/dom/HTMLDNSPrefetch.h"
51 #include "nsEscape.h"
52 #include "SerializedLoadContext.h"
53 #include "nsAuthInformationHolder.h"
54 #include "nsINetworkPredictor.h"
55 #include "nsINetworkPredictorVerifier.h"
56 #include "nsISpeculativeConnect.h"
57 #include "nsHttpHandler.h"
58 #include "nsNetUtil.h"
59 #include "nsIOService.h"
61 using IPC::SerializedLoadContext;
62 using mozilla::dom::BrowserParent;
63 using mozilla::dom::ContentParent;
64 using mozilla::dom::TCPServerSocketParent;
65 using mozilla::dom::TCPSocketParent;
66 using mozilla::dom::UDPSocketParent;
67 using mozilla::ipc::LoadInfoArgsToLoadInfo;
68 using mozilla::ipc::PrincipalInfo;
69 #ifdef MOZ_PLACES
70 using mozilla::places::PageIconProtocolHandler;
71 #endif
73 namespace mozilla {
74 namespace net {
76 // C++ file contents
77 NeckoParent::NeckoParent() : mSocketProcessBridgeInited(false) {
78 // Init HTTP protocol handler now since we need atomTable up and running very
79 // early (IPDL argument handling for PHttpChannel constructor needs it) so
80 // normal init (during 1st Http channel request) isn't early enough.
81 nsCOMPtr<nsIProtocolHandler> proto =
82 do_GetService("@mozilla.org/network/protocol;1?name=http");
85 static PBOverrideStatus PBOverrideStatusFromLoadContext(
86 const SerializedLoadContext& aSerialized) {
87 if (!aSerialized.IsNotNull() && aSerialized.IsPrivateBitValid()) {
88 return (aSerialized.mOriginAttributes.mPrivateBrowsingId > 0)
89 ? kPBOverride_Private
90 : kPBOverride_NotPrivate;
92 return kPBOverride_Unset;
95 static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
96 const LoadInfoArgs& aLoadInfoArgs) {
97 const Maybe<PrincipalInfo>& optionalPrincipalInfo =
98 aLoadInfoArgs.requestingPrincipalInfo();
100 if (optionalPrincipalInfo.isNothing()) {
101 return nullptr;
104 const PrincipalInfo& principalInfo = optionalPrincipalInfo.ref();
106 auto principalOrErr = PrincipalInfoToPrincipal(principalInfo);
107 return principalOrErr.isOk() ? principalOrErr.unwrap().forget() : nullptr;
110 static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
111 const HttpChannelCreationArgs& aArgs) {
112 if (aArgs.type() != HttpChannelCreationArgs::THttpChannelOpenArgs) {
113 return nullptr;
116 const HttpChannelOpenArgs& args = aArgs.get_HttpChannelOpenArgs();
117 return GetRequestingPrincipal(args.loadInfo());
120 const char* NeckoParent::GetValidatedOriginAttributes(
121 const SerializedLoadContext& aSerialized, PContentParent* aContent,
122 nsIPrincipal* aRequestingPrincipal, OriginAttributes& aAttrs) {
123 if (!aSerialized.IsNotNull()) {
124 // If serialized is null, we cannot validate anything. We have to assume
125 // that this requests comes from a SystemPrincipal.
126 aAttrs = OriginAttributes();
127 } else {
128 aAttrs = aSerialized.mOriginAttributes;
130 return nullptr;
133 const char* NeckoParent::CreateChannelLoadContext(
134 PBrowserParent* aBrowser, PContentParent* aContent,
135 const SerializedLoadContext& aSerialized,
136 nsIPrincipal* aRequestingPrincipal, nsCOMPtr<nsILoadContext>& aResult) {
137 OriginAttributes attrs;
138 const char* error = GetValidatedOriginAttributes(aSerialized, aContent,
139 aRequestingPrincipal, attrs);
140 if (error) {
141 return error;
144 // if !UsingNeckoIPCSecurity(), we may not have a LoadContext to set. This is
145 // the common case for most xpcshell tests.
146 if (aSerialized.IsNotNull()) {
147 attrs.SyncAttributesWithPrivateBrowsing(
148 aSerialized.mOriginAttributes.mPrivateBrowsingId > 0);
150 RefPtr<BrowserParent> browserParent = BrowserParent::GetFrom(aBrowser);
151 dom::Element* topFrameElement = nullptr;
152 if (browserParent) {
153 topFrameElement = browserParent->GetOwnerElement();
155 aResult = new LoadContext(aSerialized, topFrameElement, attrs);
158 return nullptr;
161 void NeckoParent::ActorDestroy(ActorDestroyReason aWhy) {
162 // Nothing needed here. Called right before destructor since this is a
163 // non-refcounted class.
166 already_AddRefed<PHttpChannelParent> NeckoParent::AllocPHttpChannelParent(
167 PBrowserParent* aBrowser, const SerializedLoadContext& aSerialized,
168 const HttpChannelCreationArgs& aOpenArgs) {
169 nsCOMPtr<nsIPrincipal> requestingPrincipal =
170 GetRequestingPrincipal(aOpenArgs);
172 nsCOMPtr<nsILoadContext> loadContext;
173 const char* error = CreateChannelLoadContext(
174 aBrowser, Manager(), aSerialized, requestingPrincipal, loadContext);
175 if (error) {
176 printf_stderr(
177 "NeckoParent::AllocPHttpChannelParent: "
178 "FATAL error: %s: KILLING CHILD PROCESS\n",
179 error);
180 return nullptr;
182 PBOverrideStatus overrideStatus =
183 PBOverrideStatusFromLoadContext(aSerialized);
184 RefPtr<HttpChannelParent> p = new HttpChannelParent(
185 BrowserParent::GetFrom(aBrowser), loadContext, overrideStatus);
186 return p.forget();
189 mozilla::ipc::IPCResult NeckoParent::RecvPHttpChannelConstructor(
190 PHttpChannelParent* aActor, PBrowserParent* aBrowser,
191 const SerializedLoadContext& aSerialized,
192 const HttpChannelCreationArgs& aOpenArgs) {
193 HttpChannelParent* p = static_cast<HttpChannelParent*>(aActor);
194 if (!p->Init(aOpenArgs)) {
195 return IPC_FAIL_NO_REASON(this);
197 return IPC_OK();
200 PStunAddrsRequestParent* NeckoParent::AllocPStunAddrsRequestParent() {
201 #ifdef MOZ_WEBRTC
202 StunAddrsRequestParent* p = new StunAddrsRequestParent();
203 p->AddRef();
204 return p;
205 #else
206 return nullptr;
207 #endif
210 bool NeckoParent::DeallocPStunAddrsRequestParent(
211 PStunAddrsRequestParent* aActor) {
212 #ifdef MOZ_WEBRTC
213 StunAddrsRequestParent* p = static_cast<StunAddrsRequestParent*>(aActor);
214 p->Release();
215 #endif
216 return true;
219 PWebrtcTCPSocketParent* NeckoParent::AllocPWebrtcTCPSocketParent(
220 const Maybe<TabId>& aTabId) {
221 #ifdef MOZ_WEBRTC
222 WebrtcTCPSocketParent* parent = new WebrtcTCPSocketParent(aTabId);
223 parent->AddRef();
224 return parent;
225 #else
226 return nullptr;
227 #endif
230 bool NeckoParent::DeallocPWebrtcTCPSocketParent(
231 PWebrtcTCPSocketParent* aActor) {
232 #ifdef MOZ_WEBRTC
233 WebrtcTCPSocketParent* parent = static_cast<WebrtcTCPSocketParent*>(aActor);
234 parent->Release();
235 #endif
236 return true;
239 PAltDataOutputStreamParent* NeckoParent::AllocPAltDataOutputStreamParent(
240 const nsACString& type, const int64_t& predictedSize,
241 PHttpChannelParent* channel) {
242 HttpChannelParent* chan = static_cast<HttpChannelParent*>(channel);
243 nsCOMPtr<nsIAsyncOutputStream> stream;
244 nsresult rv = chan->OpenAlternativeOutputStream(type, predictedSize,
245 getter_AddRefs(stream));
246 AltDataOutputStreamParent* parent = new AltDataOutputStreamParent(stream);
247 parent->AddRef();
248 // If the return value was not NS_OK, the error code will be sent
249 // asynchronously to the child, after receiving the first message.
250 parent->SetError(rv);
251 return parent;
254 bool NeckoParent::DeallocPAltDataOutputStreamParent(
255 PAltDataOutputStreamParent* aActor) {
256 AltDataOutputStreamParent* parent =
257 static_cast<AltDataOutputStreamParent*>(aActor);
258 parent->Release();
259 return true;
262 already_AddRefed<PDocumentChannelParent>
263 NeckoParent::AllocPDocumentChannelParent(
264 const dom::MaybeDiscarded<dom::BrowsingContext>& aContext,
265 const DocumentChannelCreationArgs& args) {
266 RefPtr<DocumentChannelParent> p = new DocumentChannelParent();
267 return p.forget();
270 mozilla::ipc::IPCResult NeckoParent::RecvPDocumentChannelConstructor(
271 PDocumentChannelParent* aActor,
272 const dom::MaybeDiscarded<dom::BrowsingContext>& aContext,
273 const DocumentChannelCreationArgs& aArgs) {
274 DocumentChannelParent* p = static_cast<DocumentChannelParent*>(aActor);
276 if (aContext.IsNullOrDiscarded()) {
277 Unused << p->SendFailedAsyncOpen(NS_ERROR_FAILURE);
278 return IPC_OK();
281 if (!p->Init(aContext.get_canonical(), aArgs)) {
282 return IPC_FAIL(this, "Couldn't initialize DocumentChannel");
285 return IPC_OK();
288 PCookieServiceParent* NeckoParent::AllocPCookieServiceParent() {
289 return new CookieServiceParent();
292 bool NeckoParent::DeallocPCookieServiceParent(PCookieServiceParent* cs) {
293 delete cs;
294 return true;
297 PWebSocketParent* NeckoParent::AllocPWebSocketParent(
298 PBrowserParent* browser, const SerializedLoadContext& serialized,
299 const uint32_t& aSerial) {
300 nsCOMPtr<nsILoadContext> loadContext;
301 const char* error = CreateChannelLoadContext(browser, Manager(), serialized,
302 nullptr, loadContext);
303 if (error) {
304 printf_stderr(
305 "NeckoParent::AllocPWebSocketParent: "
306 "FATAL error: %s: KILLING CHILD PROCESS\n",
307 error);
308 return nullptr;
311 RefPtr<BrowserParent> browserParent = BrowserParent::GetFrom(browser);
312 PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(serialized);
313 WebSocketChannelParent* p = new WebSocketChannelParent(
314 browserParent, loadContext, overrideStatus, aSerial);
315 p->AddRef();
316 return p;
319 bool NeckoParent::DeallocPWebSocketParent(PWebSocketParent* actor) {
320 WebSocketChannelParent* p = static_cast<WebSocketChannelParent*>(actor);
321 p->Release();
322 return true;
325 PWebSocketEventListenerParent* NeckoParent::AllocPWebSocketEventListenerParent(
326 const uint64_t& aInnerWindowID) {
327 RefPtr<WebSocketEventListenerParent> c =
328 new WebSocketEventListenerParent(aInnerWindowID);
329 return c.forget().take();
332 bool NeckoParent::DeallocPWebSocketEventListenerParent(
333 PWebSocketEventListenerParent* aActor) {
334 RefPtr<WebSocketEventListenerParent> c =
335 dont_AddRef(static_cast<WebSocketEventListenerParent*>(aActor));
336 MOZ_ASSERT(c);
337 return true;
340 already_AddRefed<PDataChannelParent> NeckoParent::AllocPDataChannelParent(
341 const uint32_t& channelId) {
342 RefPtr<DataChannelParent> p = new DataChannelParent();
343 return p.forget();
346 mozilla::ipc::IPCResult NeckoParent::RecvPDataChannelConstructor(
347 PDataChannelParent* actor, const uint32_t& channelId) {
348 DataChannelParent* p = static_cast<DataChannelParent*>(actor);
349 DebugOnly<bool> rv = p->Init(channelId);
350 MOZ_ASSERT(rv);
351 return IPC_OK();
354 #ifdef MOZ_WIDGET_GTK
355 static already_AddRefed<nsIPrincipal> GetRequestingPrincipal(
356 const GIOChannelCreationArgs& aArgs) {
357 if (aArgs.type() != GIOChannelCreationArgs::TGIOChannelOpenArgs) {
358 return nullptr;
361 const GIOChannelOpenArgs& args = aArgs.get_GIOChannelOpenArgs();
362 return GetRequestingPrincipal(args.loadInfo());
365 PGIOChannelParent* NeckoParent::AllocPGIOChannelParent(
366 PBrowserParent* aBrowser, const SerializedLoadContext& aSerialized,
367 const GIOChannelCreationArgs& aOpenArgs) {
368 nsCOMPtr<nsIPrincipal> requestingPrincipal =
369 GetRequestingPrincipal(aOpenArgs);
371 nsCOMPtr<nsILoadContext> loadContext;
372 const char* error = CreateChannelLoadContext(
373 aBrowser, Manager(), aSerialized, requestingPrincipal, loadContext);
374 if (error) {
375 printf_stderr(
376 "NeckoParent::AllocPGIOChannelParent: "
377 "FATAL error: %s: KILLING CHILD PROCESS\n",
378 error);
379 return nullptr;
381 PBOverrideStatus overrideStatus =
382 PBOverrideStatusFromLoadContext(aSerialized);
383 GIOChannelParent* p = new GIOChannelParent(BrowserParent::GetFrom(aBrowser),
384 loadContext, overrideStatus);
385 p->AddRef();
386 return p;
389 bool NeckoParent::DeallocPGIOChannelParent(PGIOChannelParent* channel) {
390 GIOChannelParent* p = static_cast<GIOChannelParent*>(channel);
391 p->Release();
392 return true;
395 mozilla::ipc::IPCResult NeckoParent::RecvPGIOChannelConstructor(
396 PGIOChannelParent* actor, PBrowserParent* aBrowser,
397 const SerializedLoadContext& aSerialized,
398 const GIOChannelCreationArgs& aOpenArgs) {
399 GIOChannelParent* p = static_cast<GIOChannelParent*>(actor);
400 DebugOnly<bool> rv = p->Init(aOpenArgs);
401 MOZ_ASSERT(rv);
402 return IPC_OK();
404 #endif
406 PSimpleChannelParent* NeckoParent::AllocPSimpleChannelParent(
407 const uint32_t& channelId) {
408 RefPtr<SimpleChannelParent> p = new SimpleChannelParent();
409 return p.forget().take();
412 bool NeckoParent::DeallocPSimpleChannelParent(PSimpleChannelParent* actor) {
413 RefPtr<SimpleChannelParent> p =
414 dont_AddRef(actor).downcast<SimpleChannelParent>();
415 return true;
418 mozilla::ipc::IPCResult NeckoParent::RecvPSimpleChannelConstructor(
419 PSimpleChannelParent* actor, const uint32_t& channelId) {
420 SimpleChannelParent* p = static_cast<SimpleChannelParent*>(actor);
421 MOZ_ALWAYS_TRUE(p->Init(channelId));
422 return IPC_OK();
425 already_AddRefed<PFileChannelParent> NeckoParent::AllocPFileChannelParent(
426 const uint32_t& channelId) {
427 RefPtr<FileChannelParent> p = new FileChannelParent();
428 return p.forget();
431 mozilla::ipc::IPCResult NeckoParent::RecvPFileChannelConstructor(
432 PFileChannelParent* actor, const uint32_t& channelId) {
433 FileChannelParent* p = static_cast<FileChannelParent*>(actor);
434 DebugOnly<bool> rv = p->Init(channelId);
435 MOZ_ASSERT(rv);
436 return IPC_OK();
439 PTCPSocketParent* NeckoParent::AllocPTCPSocketParent(
440 const nsAString& /* host */, const uint16_t& /* port */) {
441 // We actually don't need host/port to construct a TCPSocketParent since
442 // TCPSocketParent will maintain an internal nsIDOMTCPSocket instance which
443 // can be delegated to get the host/port.
444 TCPSocketParent* p = new TCPSocketParent();
445 p->AddIPDLReference();
446 return p;
449 bool NeckoParent::DeallocPTCPSocketParent(PTCPSocketParent* actor) {
450 TCPSocketParent* p = static_cast<TCPSocketParent*>(actor);
451 p->ReleaseIPDLReference();
452 return true;
455 PTCPServerSocketParent* NeckoParent::AllocPTCPServerSocketParent(
456 const uint16_t& aLocalPort, const uint16_t& aBacklog,
457 const bool& aUseArrayBuffers) {
458 TCPServerSocketParent* p =
459 new TCPServerSocketParent(this, aLocalPort, aBacklog, aUseArrayBuffers);
460 p->AddIPDLReference();
461 return p;
464 mozilla::ipc::IPCResult NeckoParent::RecvPTCPServerSocketConstructor(
465 PTCPServerSocketParent* aActor, const uint16_t& aLocalPort,
466 const uint16_t& aBacklog, const bool& aUseArrayBuffers) {
467 static_cast<TCPServerSocketParent*>(aActor)->Init();
468 return IPC_OK();
471 bool NeckoParent::DeallocPTCPServerSocketParent(PTCPServerSocketParent* actor) {
472 TCPServerSocketParent* p = static_cast<TCPServerSocketParent*>(actor);
473 p->ReleaseIPDLReference();
474 return true;
477 PUDPSocketParent* NeckoParent::AllocPUDPSocketParent(
478 nsIPrincipal* /* unused */, const nsACString& /* unused */) {
479 RefPtr<UDPSocketParent> p = new UDPSocketParent(this);
481 return p.forget().take();
484 mozilla::ipc::IPCResult NeckoParent::RecvPUDPSocketConstructor(
485 PUDPSocketParent* aActor, nsIPrincipal* aPrincipal,
486 const nsACString& aFilter) {
487 if (!static_cast<UDPSocketParent*>(aActor)->Init(aPrincipal, aFilter)) {
488 return IPC_FAIL_NO_REASON(this);
490 return IPC_OK();
493 bool NeckoParent::DeallocPUDPSocketParent(PUDPSocketParent* actor) {
494 UDPSocketParent* p = static_cast<UDPSocketParent*>(actor);
495 p->Release();
496 return true;
499 already_AddRefed<PDNSRequestParent> NeckoParent::AllocPDNSRequestParent(
500 const nsACString& aHost, const nsACString& aTrrServer, const int32_t& aPort,
501 const uint16_t& aType, const OriginAttributes& aOriginAttributes,
502 const nsIDNSService::DNSFlags& aFlags) {
503 RefPtr<DNSRequestHandler> handler = new DNSRequestHandler();
504 RefPtr<DNSRequestParent> actor = new DNSRequestParent(handler);
505 return actor.forget();
508 mozilla::ipc::IPCResult NeckoParent::RecvPDNSRequestConstructor(
509 PDNSRequestParent* aActor, const nsACString& aHost,
510 const nsACString& aTrrServer, const int32_t& aPort, const uint16_t& aType,
511 const OriginAttributes& aOriginAttributes,
512 const nsIDNSService::DNSFlags& aFlags) {
513 RefPtr<DNSRequestParent> actor = static_cast<DNSRequestParent*>(aActor);
514 RefPtr<DNSRequestHandler> handler =
515 actor->GetDNSRequest()->AsDNSRequestHandler();
516 handler->DoAsyncResolve(aHost, aTrrServer, aPort, aType, aOriginAttributes,
517 aFlags);
518 return IPC_OK();
521 mozilla::ipc::IPCResult NeckoParent::RecvSpeculativeConnect(
522 nsIURI* aURI, nsIPrincipal* aPrincipal,
523 Maybe<OriginAttributes>&& aOriginAttributes, const bool& aAnonymous) {
524 nsCOMPtr<nsISpeculativeConnect> speculator(gIOService);
525 nsCOMPtr<nsIPrincipal> principal(aPrincipal);
526 if (!aURI) {
527 return IPC_FAIL(this, "aURI must not be null");
529 if (aURI && speculator) {
530 if (aOriginAttributes) {
531 speculator->SpeculativeConnectWithOriginAttributesNative(
532 aURI, std::move(aOriginAttributes.ref()), nullptr, aAnonymous);
533 } else {
534 speculator->SpeculativeConnect(aURI, principal, nullptr, aAnonymous);
537 return IPC_OK();
540 mozilla::ipc::IPCResult NeckoParent::RecvHTMLDNSPrefetch(
541 const nsAString& hostname, const bool& isHttps,
542 const OriginAttributes& aOriginAttributes,
543 const nsIDNSService::DNSFlags& flags) {
544 dom::HTMLDNSPrefetch::Prefetch(hostname, isHttps, aOriginAttributes, flags);
545 return IPC_OK();
548 mozilla::ipc::IPCResult NeckoParent::RecvCancelHTMLDNSPrefetch(
549 const nsAString& hostname, const bool& isHttps,
550 const OriginAttributes& aOriginAttributes,
551 const nsIDNSService::DNSFlags& flags, const nsresult& reason) {
552 dom::HTMLDNSPrefetch::CancelPrefetch(hostname, isHttps, aOriginAttributes,
553 flags, reason);
554 return IPC_OK();
557 PTransportProviderParent* NeckoParent::AllocPTransportProviderParent() {
558 RefPtr<TransportProviderParent> res = new TransportProviderParent();
559 return res.forget().take();
562 bool NeckoParent::DeallocPTransportProviderParent(
563 PTransportProviderParent* aActor) {
564 RefPtr<TransportProviderParent> provider =
565 dont_AddRef(static_cast<TransportProviderParent*>(aActor));
566 return true;
569 /* Predictor Messages */
570 mozilla::ipc::IPCResult NeckoParent::RecvPredPredict(
571 nsIURI* aTargetURI, nsIURI* aSourceURI, const uint32_t& aReason,
572 const OriginAttributes& aOriginAttributes, const bool& hasVerifier) {
573 // Get the current predictor
574 nsresult rv = NS_OK;
575 nsCOMPtr<nsINetworkPredictor> predictor =
576 do_GetService("@mozilla.org/network/predictor;1", &rv);
577 NS_ENSURE_SUCCESS(rv, IPC_OK());
579 nsCOMPtr<nsINetworkPredictorVerifier> verifier;
580 if (hasVerifier) {
581 verifier = do_QueryInterface(predictor);
583 predictor->PredictNative(aTargetURI, aSourceURI, aReason, aOriginAttributes,
584 verifier);
585 return IPC_OK();
588 mozilla::ipc::IPCResult NeckoParent::RecvPredLearn(
589 nsIURI* aTargetURI, nsIURI* aSourceURI, const uint32_t& aReason,
590 const OriginAttributes& aOriginAttributes) {
591 // Get the current predictor
592 nsresult rv = NS_OK;
593 nsCOMPtr<nsINetworkPredictor> predictor =
594 do_GetService("@mozilla.org/network/predictor;1", &rv);
595 NS_ENSURE_SUCCESS(rv, IPC_OK());
597 predictor->LearnNative(aTargetURI, aSourceURI, aReason, aOriginAttributes);
598 return IPC_OK();
601 mozilla::ipc::IPCResult NeckoParent::RecvPredReset() {
602 // Get the current predictor
603 nsresult rv = NS_OK;
604 nsCOMPtr<nsINetworkPredictor> predictor =
605 do_GetService("@mozilla.org/network/predictor;1", &rv);
606 NS_ENSURE_SUCCESS(rv, IPC_OK());
608 predictor->Reset();
609 return IPC_OK();
612 mozilla::ipc::IPCResult NeckoParent::RecvRequestContextLoadBegin(
613 const uint64_t& rcid) {
614 nsCOMPtr<nsIRequestContextService> rcsvc =
615 RequestContextService::GetOrCreate();
616 if (!rcsvc) {
617 return IPC_OK();
619 nsCOMPtr<nsIRequestContext> rc;
620 rcsvc->GetRequestContext(rcid, getter_AddRefs(rc));
621 if (rc) {
622 rc->BeginLoad();
625 return IPC_OK();
628 mozilla::ipc::IPCResult NeckoParent::RecvRequestContextAfterDOMContentLoaded(
629 const uint64_t& rcid) {
630 nsCOMPtr<nsIRequestContextService> rcsvc =
631 RequestContextService::GetOrCreate();
632 if (!rcsvc) {
633 return IPC_OK();
635 nsCOMPtr<nsIRequestContext> rc;
636 rcsvc->GetRequestContext(rcid, getter_AddRefs(rc));
637 if (rc) {
638 rc->DOMContentLoaded();
641 return IPC_OK();
644 mozilla::ipc::IPCResult NeckoParent::RecvRemoveRequestContext(
645 const uint64_t& rcid) {
646 nsCOMPtr<nsIRequestContextService> rcsvc =
647 RequestContextService::GetOrCreate();
648 if (!rcsvc) {
649 return IPC_OK();
652 rcsvc->RemoveRequestContext(rcid);
654 return IPC_OK();
657 mozilla::ipc::IPCResult NeckoParent::RecvGetExtensionStream(
658 nsIURI* aURI, GetExtensionStreamResolver&& aResolve) {
659 if (!aURI) {
660 return IPC_FAIL(this, "aURI must not be null");
663 RefPtr<ExtensionProtocolHandler> ph(ExtensionProtocolHandler::GetSingleton());
664 MOZ_ASSERT(ph);
666 // Ask the ExtensionProtocolHandler to give us a new input stream for
667 // this URI. The request comes from an ExtensionProtocolHandler in the
668 // child process, but is not guaranteed to be a valid moz-extension URI,
669 // and not guaranteed to represent a resource that the child should be
670 // allowed to access. The ExtensionProtocolHandler is responsible for
671 // validating the request. Specifically, only URI's for local files that
672 // an extension is allowed to access via moz-extension URI's should be
673 // accepted.
674 nsCOMPtr<nsIInputStream> inputStream;
675 bool terminateSender = true;
676 auto inputStreamOrReason = ph->NewStream(aURI, &terminateSender);
677 if (inputStreamOrReason.isOk()) {
678 inputStream = inputStreamOrReason.unwrap();
681 // If NewStream failed, we send back an invalid stream to the child so
682 // it can handle the error. MozPromise rejection is reserved for channel
683 // errors/disconnects.
684 aResolve(inputStream);
686 if (terminateSender) {
687 return IPC_FAIL_NO_REASON(this);
689 return IPC_OK();
692 mozilla::ipc::IPCResult NeckoParent::RecvGetExtensionFD(
693 nsIURI* aURI, GetExtensionFDResolver&& aResolve) {
694 if (!aURI) {
695 return IPC_FAIL(this, "aURI must not be null");
698 RefPtr<ExtensionProtocolHandler> ph(ExtensionProtocolHandler::GetSingleton());
699 MOZ_ASSERT(ph);
701 // Ask the ExtensionProtocolHandler to give us a new input stream for
702 // this URI. The request comes from an ExtensionProtocolHandler in the
703 // child process, but is not guaranteed to be a valid moz-extension URI,
704 // and not guaranteed to represent a resource that the child should be
705 // allowed to access. The ExtensionProtocolHandler is responsible for
706 // validating the request. Specifically, only URI's for local files that
707 // an extension is allowed to access via moz-extension URI's should be
708 // accepted.
709 bool terminateSender = true;
710 auto result = ph->NewFD(aURI, &terminateSender, aResolve);
712 if (result.isErr() && terminateSender) {
713 return IPC_FAIL_NO_REASON(this);
716 if (result.isErr()) {
717 FileDescriptor invalidFD;
718 aResolve(invalidFD);
721 return IPC_OK();
724 mozilla::ipc::IPCResult NeckoParent::RecvInitSocketProcessBridge(
725 InitSocketProcessBridgeResolver&& aResolver) {
726 MOZ_ASSERT(NS_IsMainThread());
728 // Initing the socket process bridge must be async here in order to
729 // wait for the socket process launch before executing.
730 auto task = [self = RefPtr{this}, resolver = std::move(aResolver)]() {
731 // The content process might be already destroyed.
732 if (!self->CanSend()) {
733 return;
736 Endpoint<PSocketProcessBridgeChild> invalidEndpoint;
737 if (NS_WARN_IF(self->mSocketProcessBridgeInited)) {
738 resolver(std::move(invalidEndpoint));
739 return;
742 SocketProcessParent* parent = SocketProcessParent::GetSingleton();
743 if (NS_WARN_IF(!parent)) {
744 resolver(std::move(invalidEndpoint));
745 return;
748 Endpoint<PSocketProcessBridgeParent> parentEndpoint;
749 Endpoint<PSocketProcessBridgeChild> childEndpoint;
750 if (NS_WARN_IF(NS_FAILED(PSocketProcessBridge::CreateEndpoints(
751 parent->OtherPid(), self->Manager()->OtherPid(), &parentEndpoint,
752 &childEndpoint)))) {
753 resolver(std::move(invalidEndpoint));
754 return;
757 if (NS_WARN_IF(!parent->SendInitSocketProcessBridgeParent(
758 self->Manager()->OtherPid(), std::move(parentEndpoint)))) {
759 resolver(std::move(invalidEndpoint));
760 return;
763 resolver(std::move(childEndpoint));
764 self->mSocketProcessBridgeInited = true;
766 gIOService->CallOrWaitForSocketProcess(std::move(task));
768 return IPC_OK();
771 mozilla::ipc::IPCResult NeckoParent::RecvResetSocketProcessBridge() {
772 // SendResetSocketProcessBridge is called from
773 // SocketProcessBridgeChild::ActorDestroy if the socket process
774 // crashes. This is necessary in order to properly initialize the
775 // restarted socket process.
776 mSocketProcessBridgeInited = false;
777 return IPC_OK();
780 mozilla::ipc::IPCResult NeckoParent::RecvEnsureHSTSData(
781 EnsureHSTSDataResolver&& aResolver) {
782 auto callback = [aResolver{std::move(aResolver)}](bool aResult) {
783 aResolver(aResult);
785 RefPtr<HSTSDataCallbackWrapper> wrapper =
786 new HSTSDataCallbackWrapper(std::move(callback));
787 gHttpHandler->EnsureHSTSDataReadyNative(wrapper);
788 return IPC_OK();
791 mozilla::ipc::IPCResult NeckoParent::RecvGetPageThumbStream(
792 nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs,
793 GetPageThumbStreamResolver&& aResolver) {
794 // Only the privileged about content process is allowed to access
795 // things over the moz-page-thumb protocol. Any other content process
796 // that tries to send this should have been blocked via the
797 // ScriptSecurityManager, but if somehow the process has been tricked into
798 // sending this message, we send IPC_FAIL in order to crash that
799 // likely-compromised content process.
800 if (static_cast<ContentParent*>(Manager())->GetRemoteType() !=
801 PRIVILEGEDABOUT_REMOTE_TYPE) {
802 return IPC_FAIL(this, "Wrong process type");
805 RefPtr<PageThumbProtocolHandler> ph(PageThumbProtocolHandler::GetSingleton());
806 MOZ_ASSERT(ph);
808 // Ask the PageThumbProtocolHandler to give us a new input stream for
809 // this URI. The request comes from a PageThumbProtocolHandler in the
810 // child process, but is not guaranteed to be a valid moz-page-thumb URI,
811 // and not guaranteed to represent a resource that the child should be
812 // allowed to access. The PageThumbProtocolHandler is responsible for
813 // validating the request.
814 nsCOMPtr<nsIInputStream> inputStream;
815 bool terminateSender = true;
816 auto inputStreamPromise = ph->NewStream(aURI, &terminateSender);
818 if (terminateSender) {
819 return IPC_FAIL(this, "Malformed moz-page-thumb request");
822 inputStreamPromise->Then(
823 GetMainThreadSerialEventTarget(), __func__,
824 [aResolver](const RemoteStreamInfo& aInfo) { aResolver(Some(aInfo)); },
825 [aResolver](nsresult aRv) {
826 // If NewStream failed, we send back an invalid stream to the child so
827 // it can handle the error. MozPromise rejection is reserved for channel
828 // errors/disconnects.
829 Unused << NS_WARN_IF(NS_FAILED(aRv));
830 aResolver(Nothing());
833 return IPC_OK();
836 mozilla::ipc::IPCResult NeckoParent::RecvGetPageIconStream(
837 nsIURI* aURI, const LoadInfoArgs& aLoadInfoArgs,
838 GetPageIconStreamResolver&& aResolver) {
839 #ifdef MOZ_PLACES
840 const nsACString& remoteType =
841 ContentParent::Cast(Manager())->GetRemoteType();
843 // Only the privileged about content process is allowed to access
844 // things over the page-icon protocol. Any other content process
845 // that tries to send this should have been blocked via the
846 // ScriptSecurityManager, but if somehow the process has been tricked into
847 // sending this message, we send IPC_FAIL in order to crash that
848 // likely-compromised content process.
849 if (remoteType != PRIVILEGEDABOUT_REMOTE_TYPE) {
850 return IPC_FAIL(this, "Wrong process type");
853 nsCOMPtr<nsILoadInfo> loadInfo;
854 nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs, remoteType,
855 getter_AddRefs(loadInfo));
856 if (NS_FAILED(rv)) {
857 return IPC_FAIL(this, "Page-icon request must include loadInfo");
860 RefPtr<PageIconProtocolHandler> ph(PageIconProtocolHandler::GetSingleton());
861 MOZ_ASSERT(ph);
863 nsCOMPtr<nsIInputStream> inputStream;
864 bool terminateSender = true;
865 auto inputStreamPromise = ph->NewStream(aURI, loadInfo, &terminateSender);
867 if (terminateSender) {
868 return IPC_FAIL(this, "Malformed page-icon request");
871 inputStreamPromise->Then(
872 GetMainThreadSerialEventTarget(), __func__,
873 [aResolver](const RemoteStreamInfo& aInfo) { aResolver(Some(aInfo)); },
874 [aResolver](nsresult aRv) {
875 // If NewStream failed, we send back an invalid stream to the child so
876 // it can handle the error. MozPromise rejection is reserved for channel
877 // errors/disconnects.
878 Unused << NS_WARN_IF(NS_FAILED(aRv));
879 aResolver(Nothing());
882 return IPC_OK();
883 #else
884 return IPC_FAIL(this, "page-icon: protocol unavailable");
885 #endif
888 } // namespace net
889 } // namespace mozilla