1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=8 et tw=80 : */
3
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/. */
7
8 #include "necko-config.h"
9 #include "nsHttp.h"
10 #include "mozilla/net/NeckoParent.h"
11 #include "mozilla/net/HttpChannelParent.h"
12 #include "mozilla/net/CookieServiceParent.h"
13 #include "mozilla/net/WyciwygChannelParent.h"
14 #include "mozilla/net/FTPChannelParent.h"
15 #include "mozilla/net/WebSocketChannelParent.h"
16 #include "mozilla/net/WebSocketEventListenerParent.h"
17 #include "mozilla/net/DataChannelParent.h"
18 #include "mozilla/net/AltDataOutputStreamParent.h"
19 #include "mozilla/Unused.h"
20 #ifdef NECKO_PROTOCOL_rtsp
21 #include "mozilla/net/RtspControllerParent.h"
22 #include "mozilla/net/RtspChannelParent.h"
23 #endif
24 #include "mozilla/net/DNSRequestParent.h"
25 #include "mozilla/net/ChannelDiverterParent.h"
26 #include "mozilla/net/IPCTransportProvider.h"
27 #include "mozilla/dom/ChromeUtils.h"
28 #include "mozilla/dom/ContentParent.h"
29 #include "mozilla/dom/TabContext.h"
30 #include "mozilla/dom/TabParent.h"
31 #include "mozilla/dom/network/TCPSocketParent.h"
32 #include "mozilla/dom/network/TCPServerSocketParent.h"
33 #include "mozilla/dom/network/UDPSocketParent.h"
34 #include "mozilla/dom/workers/ServiceWorkerManager.h"
35 #include "mozilla/LoadContext.h"
36 #include "mozilla/AppProcessChecker.h"
37 #include "nsPrintfCString.h"
38 #include "nsHTMLDNSPrefetch.h"
39 #include "nsIAppsService.h"
40 #include "nsEscape.h"
41 #include "SerializedLoadContext.h"
42 #include "nsAuthInformationHolder.h"
43 #include "nsIAuthPromptCallback.h"
44 #include "nsPrincipal.h"
45 #include "nsINetworkPredictor.h"
46 #include "nsINetworkPredictorVerifier.h"
47 #include "nsISpeculativeConnect.h"
48
49 using mozilla::DocShellOriginAttributes;
50 using mozilla::NeckoOriginAttributes;
51 using mozilla::dom::ChromeUtils;
52 using mozilla::dom::ContentParent;
53 using mozilla::dom::TabContext;
54 using mozilla::dom::TabParent;
55 using mozilla::net::PTCPSocketParent;
56 using mozilla::dom::TCPSocketParent;
57 using mozilla::net::PTCPServerSocketParent;
58 using mozilla::dom::TCPServerSocketParent;
59 using mozilla::net::PUDPSocketParent;
60 using mozilla::dom::UDPSocketParent;
61 using mozilla::dom::workers::ServiceWorkerManager;
62 using mozilla::ipc::OptionalPrincipalInfo;
63 using mozilla::ipc::PrincipalInfo;
64 using IPC::SerializedLoadContext;
65
66 namespace mozilla {
67 namespace net {
68
69 // C++ file contents
NeckoParent()70 NeckoParent::NeckoParent()
71 {
72 // Init HTTP protocol handler now since we need atomTable up and running very
73 // early (IPDL argument handling for PHttpChannel constructor needs it) so
74 // normal init (during 1st Http channel request) isn't early enough.
75 nsCOMPtr<nsIProtocolHandler> proto =
76 do_GetService("@mozilla.org/network/protocol;1?name=http");
77
78 // only register once--we will have multiple NeckoParents if there are
79 // multiple child processes.
80 static bool registeredBool = false;
81 if (!registeredBool) {
82 Preferences::AddBoolVarCache(&NeckoCommonInternal::gSecurityDisabled,
83 "network.disable.ipc.security");
84 registeredBool = true;
85 }
86 }
87
~NeckoParent()88 NeckoParent::~NeckoParent()
89 {
90 }
91
92 static PBOverrideStatus
PBOverrideStatusFromLoadContext(const SerializedLoadContext & aSerialized)93 PBOverrideStatusFromLoadContext(const SerializedLoadContext& aSerialized)
94 {
95 if (!aSerialized.IsNotNull() && aSerialized.IsPrivateBitValid()) {
96 return (aSerialized.mOriginAttributes.mPrivateBrowsingId > 0) ?
97 kPBOverride_Private :
98 kPBOverride_NotPrivate;
99 }
100 return kPBOverride_Unset;
101 }
102
103 static already_AddRefed<nsIPrincipal>
GetRequestingPrincipal(const OptionalLoadInfoArgs aOptionalLoadInfoArgs)104 GetRequestingPrincipal(const OptionalLoadInfoArgs aOptionalLoadInfoArgs)
105 {
106 if (aOptionalLoadInfoArgs.type() != OptionalLoadInfoArgs::TLoadInfoArgs) {
107 return nullptr;
108 }
109
110 const LoadInfoArgs& loadInfoArgs = aOptionalLoadInfoArgs.get_LoadInfoArgs();
111 const OptionalPrincipalInfo& optionalPrincipalInfo =
112 loadInfoArgs.requestingPrincipalInfo();
113
114 if (optionalPrincipalInfo.type() != OptionalPrincipalInfo::TPrincipalInfo) {
115 return nullptr;
116 }
117
118 const PrincipalInfo& principalInfo =
119 optionalPrincipalInfo.get_PrincipalInfo();
120
121 return PrincipalInfoToPrincipal(principalInfo);
122 }
123
124 static already_AddRefed<nsIPrincipal>
GetRequestingPrincipal(const HttpChannelCreationArgs & aArgs)125 GetRequestingPrincipal(const HttpChannelCreationArgs& aArgs)
126 {
127 if (aArgs.type() != HttpChannelCreationArgs::THttpChannelOpenArgs) {
128 return nullptr;
129 }
130
131 const HttpChannelOpenArgs& args = aArgs.get_HttpChannelOpenArgs();
132 return GetRequestingPrincipal(args.loadInfo());
133 }
134
135 static already_AddRefed<nsIPrincipal>
GetRequestingPrincipal(const FTPChannelCreationArgs & aArgs)136 GetRequestingPrincipal(const FTPChannelCreationArgs& aArgs)
137 {
138 if (aArgs.type() != FTPChannelCreationArgs::TFTPChannelOpenArgs) {
139 return nullptr;
140 }
141
142 const FTPChannelOpenArgs& args = aArgs.get_FTPChannelOpenArgs();
143 return GetRequestingPrincipal(args.loadInfo());
144 }
145
146 // Bug 1289001 - If GetValidatedOriginAttributes returns an error string, that
147 // usually leads to a content crash with very little info about the cause.
148 // We prefer to crash on the parent, so we get the reason in the crash report.
149 static MOZ_COLD
CrashWithReason(const char * reason)150 void CrashWithReason(const char * reason)
151 {
152 #ifndef RELEASE_OR_BETA
153 MOZ_CRASH_UNSAFE_OOL(reason);
154 #endif
155 }
156
157 const char*
GetValidatedOriginAttributes(const SerializedLoadContext & aSerialized,PContentParent * aContent,nsIPrincipal * aRequestingPrincipal,DocShellOriginAttributes & aAttrs)158 NeckoParent::GetValidatedOriginAttributes(const SerializedLoadContext& aSerialized,
159 PContentParent* aContent,
160 nsIPrincipal* aRequestingPrincipal,
161 DocShellOriginAttributes& aAttrs)
162 {
163 if (!UsingNeckoIPCSecurity()) {
164 if (!aSerialized.IsNotNull()) {
165 // If serialized is null, we cannot validate anything. We have to assume
166 // that this requests comes from a SystemPrincipal.
167 aAttrs = DocShellOriginAttributes(NECKO_NO_APP_ID, false);
168 } else {
169 aAttrs = aSerialized.mOriginAttributes;
170 }
171 return nullptr;
172 }
173
174 if (!aSerialized.IsNotNull()) {
175 CrashWithReason("GetValidatedOriginAttributes | SerializedLoadContext from child is null");
176 return "SerializedLoadContext from child is null";
177 }
178
179 nsTArray<TabContext> contextArray =
180 static_cast<ContentParent*>(aContent)->GetManagedTabContext();
181
182 nsAutoCString serializedSuffix;
183 aSerialized.mOriginAttributes.CreateAnonymizedSuffix(serializedSuffix);
184
185 nsAutoCString debugString;
186 for (uint32_t i = 0; i < contextArray.Length(); i++) {
187 const TabContext& tabContext = contextArray[i];
188
189 if (!ChromeUtils::IsOriginAttributesEqual(aSerialized.mOriginAttributes,
190 tabContext.OriginAttributesRef())) {
191 debugString.Append("(");
192 debugString.Append(serializedSuffix);
193 debugString.Append(",");
194
195 nsAutoCString tabSuffix;
196 tabContext.OriginAttributesRef().CreateAnonymizedSuffix(tabSuffix);
197 debugString.Append(tabSuffix);
198
199 debugString.Append(")");
200 continue;
201 }
202
203 aAttrs = aSerialized.mOriginAttributes;
204 return nullptr;
205 }
206
207 // This may be a ServiceWorker: when a push notification is received, FF wakes
208 // up the corrisponding service worker so that it can manage the PushEvent. At
209 // that time we probably don't have any valid tabcontext, but still, we want
210 // to support http channel requests coming from that ServiceWorker.
211 if (aRequestingPrincipal) {
212 RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
213 if (swm &&
214 swm->MayHaveActiveServiceWorkerInstance(static_cast<ContentParent*>(aContent),
215 aRequestingPrincipal)) {
216 aAttrs = aSerialized.mOriginAttributes;
217 return nullptr;
218 }
219 }
220
221 nsAutoCString errorString;
222 errorString.Append("GetValidatedOriginAttributes | App does not have permission -");
223 errorString.Append(debugString);
224
225 // Leak the buffer on the heap to make sure that it lives long enough, as
226 // MOZ_CRASH_ANNOTATE expects the pointer passed to it to live to the end of
227 // the program.
228 char * error = strdup(errorString.BeginReading());
229 CrashWithReason(error);
230 return "App does not have permission";
231 }
232
233 const char *
CreateChannelLoadContext(const PBrowserOrId & aBrowser,PContentParent * aContent,const SerializedLoadContext & aSerialized,nsIPrincipal * aRequestingPrincipal,nsCOMPtr<nsILoadContext> & aResult)234 NeckoParent::CreateChannelLoadContext(const PBrowserOrId& aBrowser,
235 PContentParent* aContent,
236 const SerializedLoadContext& aSerialized,
237 nsIPrincipal* aRequestingPrincipal,
238 nsCOMPtr<nsILoadContext> &aResult)
239 {
240 DocShellOriginAttributes attrs;
241 const char* error = GetValidatedOriginAttributes(aSerialized, aContent,
242 aRequestingPrincipal, attrs);
243 if (error) {
244 return error;
245 }
246
247 // if !UsingNeckoIPCSecurity(), we may not have a LoadContext to set. This is
248 // the common case for most xpcshell tests.
249 if (aSerialized.IsNotNull()) {
250 attrs.SyncAttributesWithPrivateBrowsing(aSerialized.mOriginAttributes.mPrivateBrowsingId > 0);
251 switch (aBrowser.type()) {
252 case PBrowserOrId::TPBrowserParent:
253 {
254 RefPtr<TabParent> tabParent =
255 TabParent::GetFrom(aBrowser.get_PBrowserParent());
256 dom::Element* topFrameElement = nullptr;
257 if (tabParent) {
258 topFrameElement = tabParent->GetOwnerElement();
259 }
260 aResult = new LoadContext(aSerialized, topFrameElement, attrs);
261 break;
262 }
263 case PBrowserOrId::TTabId:
264 {
265 aResult = new LoadContext(aSerialized, aBrowser.get_TabId(), attrs);
266 break;
267 }
268 default:
269 MOZ_CRASH();
270 }
271 }
272
273 return nullptr;
274 }
275
276 void
ActorDestroy(ActorDestroyReason aWhy)277 NeckoParent::ActorDestroy(ActorDestroyReason aWhy)
278 {
279 // Nothing needed here. Called right before destructor since this is a
280 // non-refcounted class.
281 }
282
283 PHttpChannelParent*
AllocPHttpChannelParent(const PBrowserOrId & aBrowser,const SerializedLoadContext & aSerialized,const HttpChannelCreationArgs & aOpenArgs)284 NeckoParent::AllocPHttpChannelParent(const PBrowserOrId& aBrowser,
285 const SerializedLoadContext& aSerialized,
286 const HttpChannelCreationArgs& aOpenArgs)
287 {
288 nsCOMPtr<nsIPrincipal> requestingPrincipal =
289 GetRequestingPrincipal(aOpenArgs);
290
291 nsCOMPtr<nsILoadContext> loadContext;
292 const char *error = CreateChannelLoadContext(aBrowser, Manager(),
293 aSerialized, requestingPrincipal,
294 loadContext);
295 if (error) {
296 printf_stderr("NeckoParent::AllocPHttpChannelParent: "
297 "FATAL error: %s: KILLING CHILD PROCESS\n",
298 error);
299 return nullptr;
300 }
301 PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(aSerialized);
302 HttpChannelParent *p = new HttpChannelParent(aBrowser, loadContext, overrideStatus);
303 p->AddRef();
304 return p;
305 }
306
307 bool
DeallocPHttpChannelParent(PHttpChannelParent * channel)308 NeckoParent::DeallocPHttpChannelParent(PHttpChannelParent* channel)
309 {
310 HttpChannelParent *p = static_cast<HttpChannelParent *>(channel);
311 p->Release();
312 return true;
313 }
314
315 bool
RecvPHttpChannelConstructor(PHttpChannelParent * aActor,const PBrowserOrId & aBrowser,const SerializedLoadContext & aSerialized,const HttpChannelCreationArgs & aOpenArgs)316 NeckoParent::RecvPHttpChannelConstructor(
317 PHttpChannelParent* aActor,
318 const PBrowserOrId& aBrowser,
319 const SerializedLoadContext& aSerialized,
320 const HttpChannelCreationArgs& aOpenArgs)
321 {
322 HttpChannelParent* p = static_cast<HttpChannelParent*>(aActor);
323 return p->Init(aOpenArgs);
324 }
325
326 PAltDataOutputStreamParent*
AllocPAltDataOutputStreamParent(const nsCString & type,PHttpChannelParent * channel)327 NeckoParent::AllocPAltDataOutputStreamParent(
328 const nsCString& type,
329 PHttpChannelParent* channel)
330 {
331 HttpChannelParent* chan = static_cast<HttpChannelParent*>(channel);
332 nsCOMPtr<nsIOutputStream> stream;
333 nsresult rv = chan->OpenAlternativeOutputStream(type, getter_AddRefs(stream));
334 AltDataOutputStreamParent* parent = new AltDataOutputStreamParent(stream);
335 parent->AddRef();
336 // If the return value was not NS_OK, the error code will be sent
337 // asynchronously to the child, after receiving the first message.
338 parent->SetError(rv);
339 return parent;
340 }
341
342 bool
DeallocPAltDataOutputStreamParent(PAltDataOutputStreamParent * aActor)343 NeckoParent::DeallocPAltDataOutputStreamParent(PAltDataOutputStreamParent* aActor)
344 {
345 AltDataOutputStreamParent* parent = static_cast<AltDataOutputStreamParent*>(aActor);
346 parent->Release();
347 return true;
348 }
349
350 PFTPChannelParent*
AllocPFTPChannelParent(const PBrowserOrId & aBrowser,const SerializedLoadContext & aSerialized,const FTPChannelCreationArgs & aOpenArgs)351 NeckoParent::AllocPFTPChannelParent(const PBrowserOrId& aBrowser,
352 const SerializedLoadContext& aSerialized,
353 const FTPChannelCreationArgs& aOpenArgs)
354 {
355 nsCOMPtr<nsIPrincipal> requestingPrincipal =
356 GetRequestingPrincipal(aOpenArgs);
357
358 nsCOMPtr<nsILoadContext> loadContext;
359 const char *error = CreateChannelLoadContext(aBrowser, Manager(),
360 aSerialized, requestingPrincipal,
361 loadContext);
362 if (error) {
363 printf_stderr("NeckoParent::AllocPFTPChannelParent: "
364 "FATAL error: %s: KILLING CHILD PROCESS\n",
365 error);
366 return nullptr;
367 }
368 PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(aSerialized);
369 FTPChannelParent *p = new FTPChannelParent(aBrowser, loadContext, overrideStatus);
370 p->AddRef();
371 return p;
372 }
373
374 bool
DeallocPFTPChannelParent(PFTPChannelParent * channel)375 NeckoParent::DeallocPFTPChannelParent(PFTPChannelParent* channel)
376 {
377 FTPChannelParent *p = static_cast<FTPChannelParent *>(channel);
378 p->Release();
379 return true;
380 }
381
382 bool
RecvPFTPChannelConstructor(PFTPChannelParent * aActor,const PBrowserOrId & aBrowser,const SerializedLoadContext & aSerialized,const FTPChannelCreationArgs & aOpenArgs)383 NeckoParent::RecvPFTPChannelConstructor(
384 PFTPChannelParent* aActor,
385 const PBrowserOrId& aBrowser,
386 const SerializedLoadContext& aSerialized,
387 const FTPChannelCreationArgs& aOpenArgs)
388 {
389 FTPChannelParent* p = static_cast<FTPChannelParent*>(aActor);
390 return p->Init(aOpenArgs);
391 }
392
393 PCookieServiceParent*
AllocPCookieServiceParent()394 NeckoParent::AllocPCookieServiceParent()
395 {
396 return new CookieServiceParent();
397 }
398
399 bool
DeallocPCookieServiceParent(PCookieServiceParent * cs)400 NeckoParent::DeallocPCookieServiceParent(PCookieServiceParent* cs)
401 {
402 delete cs;
403 return true;
404 }
405
406 PWyciwygChannelParent*
AllocPWyciwygChannelParent()407 NeckoParent::AllocPWyciwygChannelParent()
408 {
409 WyciwygChannelParent *p = new WyciwygChannelParent();
410 p->AddRef();
411 return p;
412 }
413
414 bool
DeallocPWyciwygChannelParent(PWyciwygChannelParent * channel)415 NeckoParent::DeallocPWyciwygChannelParent(PWyciwygChannelParent* channel)
416 {
417 WyciwygChannelParent *p = static_cast<WyciwygChannelParent *>(channel);
418 p->Release();
419 return true;
420 }
421
422 PWebSocketParent*
AllocPWebSocketParent(const PBrowserOrId & browser,const SerializedLoadContext & serialized,const uint32_t & aSerial)423 NeckoParent::AllocPWebSocketParent(const PBrowserOrId& browser,
424 const SerializedLoadContext& serialized,
425 const uint32_t& aSerial)
426 {
427 nsCOMPtr<nsILoadContext> loadContext;
428 const char *error = CreateChannelLoadContext(browser, Manager(),
429 serialized,
430 nullptr,
431 loadContext);
432 if (error) {
433 printf_stderr("NeckoParent::AllocPWebSocketParent: "
434 "FATAL error: %s: KILLING CHILD PROCESS\n",
435 error);
436 return nullptr;
437 }
438
439 RefPtr<TabParent> tabParent = TabParent::GetFrom(browser.get_PBrowserParent());
440 PBOverrideStatus overrideStatus = PBOverrideStatusFromLoadContext(serialized);
441 WebSocketChannelParent* p = new WebSocketChannelParent(tabParent, loadContext,
442 overrideStatus,
443 aSerial);
444 p->AddRef();
445 return p;
446 }
447
448 bool
DeallocPWebSocketParent(PWebSocketParent * actor)449 NeckoParent::DeallocPWebSocketParent(PWebSocketParent* actor)
450 {
451 WebSocketChannelParent* p = static_cast<WebSocketChannelParent*>(actor);
452 p->Release();
453 return true;
454 }
455
456 PWebSocketEventListenerParent*
AllocPWebSocketEventListenerParent(const uint64_t & aInnerWindowID)457 NeckoParent::AllocPWebSocketEventListenerParent(const uint64_t& aInnerWindowID)
458 {
459 RefPtr<WebSocketEventListenerParent> c =
460 new WebSocketEventListenerParent(aInnerWindowID);
461 return c.forget().take();
462 }
463
464 bool
DeallocPWebSocketEventListenerParent(PWebSocketEventListenerParent * aActor)465 NeckoParent::DeallocPWebSocketEventListenerParent(PWebSocketEventListenerParent* aActor)
466 {
467 RefPtr<WebSocketEventListenerParent> c =
468 dont_AddRef(static_cast<WebSocketEventListenerParent*>(aActor));
469 MOZ_ASSERT(c);
470 return true;
471 }
472
473 PDataChannelParent*
AllocPDataChannelParent(const uint32_t & channelId)474 NeckoParent::AllocPDataChannelParent(const uint32_t &channelId)
475 {
476 RefPtr<DataChannelParent> p = new DataChannelParent();
477 return p.forget().take();
478 }
479
480 bool
DeallocPDataChannelParent(PDataChannelParent * actor)481 NeckoParent::DeallocPDataChannelParent(PDataChannelParent* actor)
482 {
483 RefPtr<DataChannelParent> p = dont_AddRef(static_cast<DataChannelParent*>(actor));
484 return true;
485 }
486
487 bool
RecvPDataChannelConstructor(PDataChannelParent * actor,const uint32_t & channelId)488 NeckoParent::RecvPDataChannelConstructor(PDataChannelParent* actor,
489 const uint32_t& channelId)
490 {
491 DataChannelParent* p = static_cast<DataChannelParent*>(actor);
492 DebugOnly<bool> rv = p->Init(channelId);
493 MOZ_ASSERT(rv);
494 return true;
495 }
496
497 PRtspControllerParent*
AllocPRtspControllerParent()498 NeckoParent::AllocPRtspControllerParent()
499 {
500 #ifdef NECKO_PROTOCOL_rtsp
501 RtspControllerParent* p = new RtspControllerParent();
502 p->AddRef();
503 return p;
504 #else
505 return nullptr;
506 #endif
507 }
508
509 bool
DeallocPRtspControllerParent(PRtspControllerParent * actor)510 NeckoParent::DeallocPRtspControllerParent(PRtspControllerParent* actor)
511 {
512 #ifdef NECKO_PROTOCOL_rtsp
513 RtspControllerParent* p = static_cast<RtspControllerParent*>(actor);
514 p->Release();
515 #endif
516 return true;
517 }
518
519 PRtspChannelParent*
AllocPRtspChannelParent(const RtspChannelConnectArgs & aArgs)520 NeckoParent::AllocPRtspChannelParent(const RtspChannelConnectArgs& aArgs)
521 {
522 #ifdef NECKO_PROTOCOL_rtsp
523 nsCOMPtr<nsIURI> uri = DeserializeURI(aArgs.uri());
524 RtspChannelParent *p = new RtspChannelParent(uri);
525 p->AddRef();
526 return p;
527 #else
528 return nullptr;
529 #endif
530 }
531
532 bool
RecvPRtspChannelConstructor(PRtspChannelParent * aActor,const RtspChannelConnectArgs & aConnectArgs)533 NeckoParent::RecvPRtspChannelConstructor(
534 PRtspChannelParent* aActor,
535 const RtspChannelConnectArgs& aConnectArgs)
536 {
537 #ifdef NECKO_PROTOCOL_rtsp
538 RtspChannelParent* p = static_cast<RtspChannelParent*>(aActor);
539 return p->Init(aConnectArgs);
540 #else
541 return false;
542 #endif
543 }
544
545 bool
DeallocPRtspChannelParent(PRtspChannelParent * actor)546 NeckoParent::DeallocPRtspChannelParent(PRtspChannelParent* actor)
547 {
548 #ifdef NECKO_PROTOCOL_rtsp
549 RtspChannelParent* p = static_cast<RtspChannelParent*>(actor);
550 p->Release();
551 #endif
552 return true;
553 }
554
555 PTCPSocketParent*
AllocPTCPSocketParent(const nsString &,const uint16_t &)556 NeckoParent::AllocPTCPSocketParent(const nsString& /* host */,
557 const uint16_t& /* port */)
558 {
559 // We actually don't need host/port to construct a TCPSocketParent since
560 // TCPSocketParent will maintain an internal nsIDOMTCPSocket instance which
561 // can be delegated to get the host/port.
562 TCPSocketParent* p = new TCPSocketParent();
563 p->AddIPDLReference();
564 return p;
565 }
566
567 bool
DeallocPTCPSocketParent(PTCPSocketParent * actor)568 NeckoParent::DeallocPTCPSocketParent(PTCPSocketParent* actor)
569 {
570 TCPSocketParent* p = static_cast<TCPSocketParent*>(actor);
571 p->ReleaseIPDLReference();
572 return true;
573 }
574
575 PTCPServerSocketParent*
AllocPTCPServerSocketParent(const uint16_t & aLocalPort,const uint16_t & aBacklog,const bool & aUseArrayBuffers)576 NeckoParent::AllocPTCPServerSocketParent(const uint16_t& aLocalPort,
577 const uint16_t& aBacklog,
578 const bool& aUseArrayBuffers)
579 {
580 TCPServerSocketParent* p = new TCPServerSocketParent(this, aLocalPort, aBacklog, aUseArrayBuffers);
581 p->AddIPDLReference();
582 return p;
583 }
584
585 bool
RecvPTCPServerSocketConstructor(PTCPServerSocketParent * aActor,const uint16_t & aLocalPort,const uint16_t & aBacklog,const bool & aUseArrayBuffers)586 NeckoParent::RecvPTCPServerSocketConstructor(PTCPServerSocketParent* aActor,
587 const uint16_t& aLocalPort,
588 const uint16_t& aBacklog,
589 const bool& aUseArrayBuffers)
590 {
591 static_cast<TCPServerSocketParent*>(aActor)->Init();
592 return true;
593 }
594
595 bool
DeallocPTCPServerSocketParent(PTCPServerSocketParent * actor)596 NeckoParent::DeallocPTCPServerSocketParent(PTCPServerSocketParent* actor)
597 {
598 TCPServerSocketParent* p = static_cast<TCPServerSocketParent*>(actor);
599 p->ReleaseIPDLReference();
600 return true;
601 }
602
603 PUDPSocketParent*
AllocPUDPSocketParent(const Principal &,const nsCString &)604 NeckoParent::AllocPUDPSocketParent(const Principal& /* unused */,
605 const nsCString& /* unused */)
606 {
607 RefPtr<UDPSocketParent> p = new UDPSocketParent(this);
608
609 return p.forget().take();
610 }
611
612 bool
RecvPUDPSocketConstructor(PUDPSocketParent * aActor,const Principal & aPrincipal,const nsCString & aFilter)613 NeckoParent::RecvPUDPSocketConstructor(PUDPSocketParent* aActor,
614 const Principal& aPrincipal,
615 const nsCString& aFilter)
616 {
617 return static_cast<UDPSocketParent*>(aActor)->Init(aPrincipal, aFilter);
618 }
619
620 bool
DeallocPUDPSocketParent(PUDPSocketParent * actor)621 NeckoParent::DeallocPUDPSocketParent(PUDPSocketParent* actor)
622 {
623 UDPSocketParent* p = static_cast<UDPSocketParent*>(actor);
624 p->Release();
625 return true;
626 }
627
628 PDNSRequestParent*
AllocPDNSRequestParent(const nsCString & aHost,const uint32_t & aFlags,const nsCString & aNetworkInterface)629 NeckoParent::AllocPDNSRequestParent(const nsCString& aHost,
630 const uint32_t& aFlags,
631 const nsCString& aNetworkInterface)
632 {
633 DNSRequestParent *p = new DNSRequestParent();
634 p->AddRef();
635 return p;
636 }
637
638 bool
RecvPDNSRequestConstructor(PDNSRequestParent * aActor,const nsCString & aHost,const uint32_t & aFlags,const nsCString & aNetworkInterface)639 NeckoParent::RecvPDNSRequestConstructor(PDNSRequestParent* aActor,
640 const nsCString& aHost,
641 const uint32_t& aFlags,
642 const nsCString& aNetworkInterface)
643 {
644 static_cast<DNSRequestParent*>(aActor)->DoAsyncResolve(aHost, aFlags,
645 aNetworkInterface);
646 return true;
647 }
648
649 bool
DeallocPDNSRequestParent(PDNSRequestParent * aParent)650 NeckoParent::DeallocPDNSRequestParent(PDNSRequestParent* aParent)
651 {
652 DNSRequestParent *p = static_cast<DNSRequestParent*>(aParent);
653 p->Release();
654 return true;
655 }
656
657 bool
RecvSpeculativeConnect(const URIParams & aURI,const Principal & aPrincipal,const bool & aAnonymous)658 NeckoParent::RecvSpeculativeConnect(const URIParams& aURI,
659 const Principal& aPrincipal,
660 const bool& aAnonymous)
661 {
662 nsCOMPtr<nsISpeculativeConnect> speculator(gIOService);
663 nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
664 nsCOMPtr<nsIPrincipal> principal(aPrincipal);
665 if (uri && speculator) {
666 if (aAnonymous) {
667 speculator->SpeculativeAnonymousConnect2(uri, principal, nullptr);
668 } else {
669 speculator->SpeculativeConnect2(uri, principal, nullptr);
670 }
671
672 }
673 return true;
674 }
675
676 bool
RecvHTMLDNSPrefetch(const nsString & hostname,const uint16_t & flags)677 NeckoParent::RecvHTMLDNSPrefetch(const nsString& hostname,
678 const uint16_t& flags)
679 {
680 nsHTMLDNSPrefetch::Prefetch(hostname, flags);
681 return true;
682 }
683
684 bool
RecvCancelHTMLDNSPrefetch(const nsString & hostname,const uint16_t & flags,const nsresult & reason)685 NeckoParent::RecvCancelHTMLDNSPrefetch(const nsString& hostname,
686 const uint16_t& flags,
687 const nsresult& reason)
688 {
689 nsHTMLDNSPrefetch::CancelPrefetch(hostname, flags, reason);
690 return true;
691 }
692
693 PChannelDiverterParent*
AllocPChannelDiverterParent(const ChannelDiverterArgs & channel)694 NeckoParent::AllocPChannelDiverterParent(const ChannelDiverterArgs& channel)
695 {
696 return new ChannelDiverterParent();
697 }
698
699 bool
RecvPChannelDiverterConstructor(PChannelDiverterParent * actor,const ChannelDiverterArgs & channel)700 NeckoParent::RecvPChannelDiverterConstructor(PChannelDiverterParent* actor,
701 const ChannelDiverterArgs& channel)
702 {
703 auto parent = static_cast<ChannelDiverterParent*>(actor);
704 parent->Init(channel);
705 return true;
706 }
707
708 bool
DeallocPChannelDiverterParent(PChannelDiverterParent * parent)709 NeckoParent::DeallocPChannelDiverterParent(PChannelDiverterParent* parent)
710 {
711 delete static_cast<ChannelDiverterParent*>(parent);
712 return true;
713 }
714
715 PTransportProviderParent*
AllocPTransportProviderParent()716 NeckoParent::AllocPTransportProviderParent()
717 {
718 RefPtr<TransportProviderParent> res = new TransportProviderParent();
719 return res.forget().take();
720 }
721
722 bool
DeallocPTransportProviderParent(PTransportProviderParent * aActor)723 NeckoParent::DeallocPTransportProviderParent(PTransportProviderParent* aActor)
724 {
725 RefPtr<TransportProviderParent> provider =
726 dont_AddRef(static_cast<TransportProviderParent*>(aActor));
727 return true;
728 }
729
730 namespace {
731 std::map<uint64_t, nsCOMPtr<nsIAuthPromptCallback> >&
CallbackMap()732 CallbackMap()
733 {
734 MOZ_ASSERT(NS_IsMainThread());
735 static std::map<uint64_t, nsCOMPtr<nsIAuthPromptCallback> > sCallbackMap;
736 return sCallbackMap;
737 }
738 } // namespace
739
NS_IMPL_ISUPPORTS(NeckoParent::NestedFrameAuthPrompt,nsIAuthPrompt2)740 NS_IMPL_ISUPPORTS(NeckoParent::NestedFrameAuthPrompt, nsIAuthPrompt2)
741
742 NeckoParent::NestedFrameAuthPrompt::NestedFrameAuthPrompt(PNeckoParent* aParent,
743 TabId aNestedFrameId)
744 : mNeckoParent(aParent)
745 , mNestedFrameId(aNestedFrameId)
746 {}
747
748 NS_IMETHODIMP
AsyncPromptAuth(nsIChannel * aChannel,nsIAuthPromptCallback * callback,nsISupports *,uint32_t,nsIAuthInformation * aInfo,nsICancelable **)749 NeckoParent::NestedFrameAuthPrompt::AsyncPromptAuth(
750 nsIChannel* aChannel, nsIAuthPromptCallback* callback,
751 nsISupports*, uint32_t,
752 nsIAuthInformation* aInfo, nsICancelable**)
753 {
754 static uint64_t callbackId = 0;
755 MOZ_ASSERT(XRE_IsParentProcess());
756 nsCOMPtr<nsIURI> uri;
757 nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
758 NS_ENSURE_SUCCESS(rv, rv);
759 nsAutoCString spec;
760 if (uri) {
761 rv = uri->GetSpec(spec);
762 NS_ENSURE_SUCCESS(rv, rv);
763 }
764 nsString realm;
765 rv = aInfo->GetRealm(realm);
766 NS_ENSURE_SUCCESS(rv, rv);
767 callbackId++;
768 if (mNeckoParent->SendAsyncAuthPromptForNestedFrame(mNestedFrameId,
769 spec,
770 realm,
771 callbackId)) {
772 CallbackMap()[callbackId] = callback;
773 return NS_OK;
774 }
775 return NS_ERROR_FAILURE;
776 }
777
778 bool
RecvOnAuthAvailable(const uint64_t & aCallbackId,const nsString & aUser,const nsString & aPassword,const nsString & aDomain)779 NeckoParent::RecvOnAuthAvailable(const uint64_t& aCallbackId,
780 const nsString& aUser,
781 const nsString& aPassword,
782 const nsString& aDomain)
783 {
784 nsCOMPtr<nsIAuthPromptCallback> callback = CallbackMap()[aCallbackId];
785 if (!callback) {
786 return true;
787 }
788 CallbackMap().erase(aCallbackId);
789
790 RefPtr<nsAuthInformationHolder> holder =
791 new nsAuthInformationHolder(0, EmptyString(), EmptyCString());
792 holder->SetUsername(aUser);
793 holder->SetPassword(aPassword);
794 holder->SetDomain(aDomain);
795
796 callback->OnAuthAvailable(nullptr, holder);
797 return true;
798 }
799
800 bool
RecvOnAuthCancelled(const uint64_t & aCallbackId,const bool & aUserCancel)801 NeckoParent::RecvOnAuthCancelled(const uint64_t& aCallbackId,
802 const bool& aUserCancel)
803 {
804 nsCOMPtr<nsIAuthPromptCallback> callback = CallbackMap()[aCallbackId];
805 if (!callback) {
806 return true;
807 }
808 CallbackMap().erase(aCallbackId);
809 callback->OnAuthCancelled(nullptr, aUserCancel);
810 return true;
811 }
812
813 /* Predictor Messages */
814 bool
RecvPredPredict(const ipc::OptionalURIParams & aTargetURI,const ipc::OptionalURIParams & aSourceURI,const uint32_t & aReason,const SerializedLoadContext & aLoadContext,const bool & hasVerifier)815 NeckoParent::RecvPredPredict(const ipc::OptionalURIParams& aTargetURI,
816 const ipc::OptionalURIParams& aSourceURI,
817 const uint32_t& aReason,
818 const SerializedLoadContext& aLoadContext,
819 const bool& hasVerifier)
820 {
821 nsCOMPtr<nsIURI> targetURI = DeserializeURI(aTargetURI);
822 nsCOMPtr<nsIURI> sourceURI = DeserializeURI(aSourceURI);
823
824 // We only actually care about the loadContext.mPrivateBrowsing, so we'll just
825 // pass dummy params for nestFrameId, and originAttributes.
826 uint64_t nestedFrameId = 0;
827 DocShellOriginAttributes attrs(NECKO_UNKNOWN_APP_ID, false);
828 nsCOMPtr<nsILoadContext> loadContext;
829 if (aLoadContext.IsNotNull()) {
830 attrs.SyncAttributesWithPrivateBrowsing(aLoadContext.mOriginAttributes.mPrivateBrowsingId > 0);
831 loadContext = new LoadContext(aLoadContext, nestedFrameId, attrs);
832 }
833
834 // Get the current predictor
835 nsresult rv = NS_OK;
836 nsCOMPtr<nsINetworkPredictor> predictor =
837 do_GetService("@mozilla.org/network/predictor;1", &rv);
838 NS_ENSURE_SUCCESS(rv, false);
839
840 nsCOMPtr<nsINetworkPredictorVerifier> verifier;
841 if (hasVerifier) {
842 verifier = do_QueryInterface(predictor);
843 }
844 predictor->Predict(targetURI, sourceURI, aReason, loadContext, verifier);
845 return true;
846 }
847
848 bool
RecvPredLearn(const ipc::URIParams & aTargetURI,const ipc::OptionalURIParams & aSourceURI,const uint32_t & aReason,const SerializedLoadContext & aLoadContext)849 NeckoParent::RecvPredLearn(const ipc::URIParams& aTargetURI,
850 const ipc::OptionalURIParams& aSourceURI,
851 const uint32_t& aReason,
852 const SerializedLoadContext& aLoadContext)
853 {
854 nsCOMPtr<nsIURI> targetURI = DeserializeURI(aTargetURI);
855 nsCOMPtr<nsIURI> sourceURI = DeserializeURI(aSourceURI);
856
857 // We only actually care about the loadContext.mPrivateBrowsing, so we'll just
858 // pass dummy params for nestFrameId, and originAttributes;
859 uint64_t nestedFrameId = 0;
860 DocShellOriginAttributes attrs(NECKO_UNKNOWN_APP_ID, false);
861 nsCOMPtr<nsILoadContext> loadContext;
862 if (aLoadContext.IsNotNull()) {
863 attrs.SyncAttributesWithPrivateBrowsing(aLoadContext.mOriginAttributes.mPrivateBrowsingId > 0);
864 loadContext = new LoadContext(aLoadContext, nestedFrameId, attrs);
865 }
866
867 // Get the current predictor
868 nsresult rv = NS_OK;
869 nsCOMPtr<nsINetworkPredictor> predictor =
870 do_GetService("@mozilla.org/network/predictor;1", &rv);
871 NS_ENSURE_SUCCESS(rv, false);
872
873 predictor->Learn(targetURI, sourceURI, aReason, loadContext);
874 return true;
875 }
876
877 bool
RecvPredReset()878 NeckoParent::RecvPredReset()
879 {
880 // Get the current predictor
881 nsresult rv = NS_OK;
882 nsCOMPtr<nsINetworkPredictor> predictor =
883 do_GetService("@mozilla.org/network/predictor;1", &rv);
884 NS_ENSURE_SUCCESS(rv, false);
885
886 predictor->Reset();
887 return true;
888 }
889
890 bool
RecvRemoveRequestContext(const nsCString & rcid)891 NeckoParent::RecvRemoveRequestContext(const nsCString& rcid)
892 {
893 nsCOMPtr<nsIRequestContextService> rcsvc =
894 do_GetService("@mozilla.org/network/request-context-service;1");
895 if (!rcsvc) {
896 return true;
897 }
898
899 nsID id;
900 id.Parse(rcid.BeginReading());
901 rcsvc->RemoveRequestContext(id);
902
903 return true;
904 }
905
906 } // namespace net
907 } // namespace mozilla
908