Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "mozilla/dom/FlyWebPublishedServerIPC.h"
8 : #include "mozilla/dom/FlyWebPublishBinding.h"
9 : #include "mozilla/dom/FlyWebService.h"
10 : #include "mozilla/dom/DocGroup.h"
11 : #include "mozilla/dom/Request.h"
12 : #include "mozilla/dom/FlyWebServerEvents.h"
13 : #include "mozilla/dom/ContentChild.h"
14 : #include "mozilla/dom/ContentParent.h"
15 : #include "mozilla/dom/InternalResponse.h"
16 : #include "mozilla/ipc/IPCStreamUtils.h"
17 : #include "mozilla/net/NeckoParent.h"
18 : #include "mozilla/net/IPCTransportProvider.h"
19 : #include "mozilla/ErrorResult.h"
20 : #include "mozilla/Preferences.h"
21 : #include "mozilla/Unused.h"
22 : #include "nsCharSeparatedTokenizer.h"
23 : #include "nsGlobalWindow.h"
24 : #include "WebSocketChannel.h"
25 :
26 : namespace mozilla {
27 : namespace dom {
28 :
29 : static LazyLogModule gFlyWebPublishedServerLog("FlyWebPublishedServer");
30 : #undef LOG_I
31 : #define LOG_I(...) MOZ_LOG(mozilla::dom::gFlyWebPublishedServerLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
32 : #undef LOG_E
33 : #define LOG_E(...) MOZ_LOG(mozilla::dom::gFlyWebPublishedServerLog, mozilla::LogLevel::Error, (__VA_ARGS__))
34 :
35 : /******** FlyWebPublishedServer ********/
36 :
37 0 : FlyWebPublishedServer::FlyWebPublishedServer(nsPIDOMWindowInner* aOwner,
38 : const nsAString& aName,
39 0 : const FlyWebPublishOptions& aOptions)
40 : : mozilla::DOMEventTargetHelper(aOwner)
41 0 : , mOwnerWindowID(aOwner ? aOwner->WindowID() : 0)
42 : , mName(aName)
43 : , mUiUrl(aOptions.mUiUrl)
44 0 : , mIsRegistered(true) // Registered by the FlyWebService
45 : {
46 0 : }
47 :
48 : void
49 0 : FlyWebPublishedServer::LastRelease()
50 : {
51 : // Make sure to unregister to avoid dangling pointers. Use the LastRelease
52 : // hook rather than dtor since calling virtual functions during dtor
53 : // wouldn't do what we want. Also, LastRelease is called earlier than dtor
54 : // for CC objects.
55 0 : Close();
56 0 : }
57 :
58 : JSObject*
59 0 : FlyWebPublishedServer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
60 : {
61 0 : return FlyWebPublishedServerBinding::Wrap(aCx, this, aGivenProto);
62 : }
63 :
64 : void
65 0 : FlyWebPublishedServer::Close()
66 : {
67 0 : LOG_I("FlyWebPublishedServer::Close(%p)", this);
68 :
69 : // Unregister from server.
70 0 : if (mIsRegistered) {
71 0 : MOZ_ASSERT(FlyWebService::GetExisting());
72 0 : FlyWebService::GetExisting()->UnregisterServer(this);
73 0 : mIsRegistered = false;
74 :
75 0 : DispatchTrustedEvent(NS_LITERAL_STRING("close"));
76 : }
77 0 : }
78 :
79 : void
80 0 : FlyWebPublishedServer::FireFetchEvent(InternalRequest* aRequest)
81 : {
82 0 : nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
83 : RefPtr<FlyWebFetchEvent> e = new FlyWebFetchEvent(this,
84 0 : new Request(global, aRequest),
85 0 : aRequest);
86 0 : e->Init(this);
87 0 : e->InitEvent(NS_LITERAL_STRING("fetch"), false, false);
88 :
89 0 : DispatchTrustedEvent(e);
90 0 : }
91 :
92 : void
93 0 : FlyWebPublishedServer::FireWebsocketEvent(InternalRequest* aConnectRequest)
94 : {
95 0 : nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
96 : RefPtr<FlyWebFetchEvent> e = new FlyWebWebSocketEvent(this,
97 0 : new Request(global, aConnectRequest),
98 0 : aConnectRequest);
99 0 : e->Init(this);
100 0 : e->InitEvent(NS_LITERAL_STRING("websocket"), false, false);
101 :
102 0 : DispatchTrustedEvent(e);
103 0 : }
104 :
105 : void
106 0 : FlyWebPublishedServer::PublishedServerStarted(nsresult aStatus)
107 : {
108 0 : LOG_I("FlyWebPublishedServer::PublishedServerStarted(%p)", this);
109 :
110 0 : RefPtr<FlyWebPublishPromise> promise = mPublishPromise.Ensure(__func__);
111 0 : if (NS_SUCCEEDED(aStatus)) {
112 0 : mPublishPromise.Resolve(this, __func__);
113 : } else {
114 0 : Close();
115 0 : mPublishPromise.Reject(aStatus, __func__);
116 : }
117 0 : }
118 :
119 : already_AddRefed<WebSocket>
120 0 : FlyWebPublishedServer::OnWebSocketAccept(InternalRequest* aConnectRequest,
121 : const Optional<nsAString>& aProtocol,
122 : ErrorResult& aRv)
123 : {
124 0 : MOZ_ASSERT(aConnectRequest);
125 :
126 0 : LOG_I("FlyWebPublishedServer::OnWebSocketAccept(%p)", this);
127 :
128 : nsCOMPtr<nsITransportProvider> provider =
129 0 : OnWebSocketAcceptInternal(aConnectRequest,
130 : aProtocol,
131 0 : aRv);
132 0 : if (aRv.Failed()) {
133 0 : return nullptr;
134 : }
135 0 : MOZ_ASSERT(provider);
136 :
137 0 : nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetOwner());
138 0 : AutoJSContext cx;
139 0 : GlobalObject global(cx, nsGlobalWindow::Cast(window)->FastGetGlobalJSObject());
140 :
141 0 : nsAutoCString extensions, negotiatedExtensions;
142 : aConnectRequest->Headers()->
143 0 : GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Extensions"), extensions, aRv);
144 : mozilla::net::ProcessServerWebSocketExtensions(extensions,
145 0 : negotiatedExtensions);
146 :
147 0 : nsCString url;
148 0 : aConnectRequest->GetURL(url);
149 0 : Sequence<nsString> protocols;
150 0 : if (aProtocol.WasPassed() &&
151 0 : !protocols.AppendElement(aProtocol.Value(), fallible)) {
152 0 : aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
153 0 : return nullptr;
154 : }
155 :
156 : return WebSocket::ConstructorCommon(global,
157 0 : NS_ConvertUTF8toUTF16(url),
158 : protocols,
159 : provider,
160 : negotiatedExtensions,
161 0 : aRv);
162 : }
163 :
164 : /******** FlyWebPublishedServerImpl ********/
165 :
166 0 : NS_IMPL_ISUPPORTS_INHERITED0(FlyWebPublishedServerImpl, mozilla::DOMEventTargetHelper)
167 :
168 0 : FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(nsPIDOMWindowInner* aOwner,
169 : const nsAString& aName,
170 0 : const FlyWebPublishOptions& aOptions)
171 : : FlyWebPublishedServer(aOwner, aName, aOptions)
172 : , mHttpServer(
173 0 : new HttpServer(aOwner ?
174 0 : aOwner->GetDocGroup()->EventTargetFor(TaskCategory::Other) :
175 0 : GetMainThreadSerialEventTarget()))
176 : {
177 0 : LOG_I("FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(%p)", this);
178 0 : }
179 :
180 : void
181 0 : FlyWebPublishedServerImpl::PermissionGranted(bool aGranted)
182 : {
183 0 : LOG_I("FlyWebPublishedServerImpl::PermissionGranted(%d)", aGranted);
184 0 : if (!aGranted) {
185 0 : PublishedServerStarted(NS_ERROR_FAILURE);
186 0 : return;
187 : }
188 :
189 0 : mHttpServer->Init(-1, Preferences::GetBool("flyweb.use-tls", false), this);
190 : }
191 :
192 : void
193 0 : FlyWebPublishedServerImpl::Close()
194 : {
195 0 : FlyWebPublishedServer::Close();
196 :
197 0 : if (mMDNSCancelRegister) {
198 0 : mMDNSCancelRegister->Cancel(NS_BINDING_ABORTED);
199 0 : mMDNSCancelRegister = nullptr;
200 : }
201 :
202 0 : if (mHttpServer) {
203 0 : RefPtr<HttpServer> server = mHttpServer.forget();
204 0 : server->Close();
205 : }
206 0 : }
207 :
208 : void
209 0 : FlyWebPublishedServerImpl::OnServerStarted(nsresult aStatus)
210 : {
211 0 : if (NS_SUCCEEDED(aStatus)) {
212 0 : FlyWebService::GetOrCreate()->StartDiscoveryOf(this);
213 : } else {
214 0 : PublishedServerStarted(aStatus);
215 : }
216 0 : }
217 :
218 : void
219 0 : FlyWebPublishedServerImpl::OnFetchResponse(InternalRequest* aRequest,
220 : InternalResponse* aResponse)
221 : {
222 0 : MOZ_ASSERT(aRequest);
223 0 : MOZ_ASSERT(aResponse);
224 :
225 0 : LOG_I("FlyWebPublishedServerImpl::OnFetchResponse(%p)", this);
226 :
227 0 : if (mHttpServer) {
228 0 : mHttpServer->SendResponse(aRequest, aResponse);
229 : }
230 0 : }
231 :
232 : void
233 0 : FlyWebPublishedServerImpl::OnWebSocketResponse(InternalRequest* aConnectRequest,
234 : InternalResponse* aResponse)
235 : {
236 0 : MOZ_ASSERT(aConnectRequest);
237 0 : MOZ_ASSERT(aResponse);
238 :
239 0 : LOG_I("FlyWebPublishedMDNSServer::OnWebSocketResponse(%p)", this);
240 :
241 0 : if (mHttpServer) {
242 0 : mHttpServer->SendWebSocketResponse(aConnectRequest, aResponse);
243 : }
244 0 : }
245 :
246 : already_AddRefed<nsITransportProvider>
247 0 : FlyWebPublishedServerImpl::OnWebSocketAcceptInternal(InternalRequest* aConnectRequest,
248 : const Optional<nsAString>& aProtocol,
249 : ErrorResult& aRv)
250 : {
251 0 : LOG_I("FlyWebPublishedServerImpl::OnWebSocketAcceptInternal(%p)", this);
252 :
253 0 : if (!mHttpServer) {
254 0 : aRv.Throw(NS_ERROR_UNEXPECTED);
255 0 : return nullptr;
256 : }
257 :
258 : return mHttpServer->AcceptWebSocket(aConnectRequest,
259 : aProtocol,
260 0 : aRv);
261 : }
262 :
263 : /******** FlyWebPublishedServerChild ********/
264 :
265 0 : FlyWebPublishedServerChild::FlyWebPublishedServerChild(nsPIDOMWindowInner* aOwner,
266 : const nsAString& aName,
267 0 : const FlyWebPublishOptions& aOptions)
268 : : FlyWebPublishedServer(aOwner, aName, aOptions)
269 0 : , mActorExists(false)
270 : {
271 0 : LOG_I("FlyWebPublishedServerChild::FlyWebPublishedServerChild(%p)", this);
272 :
273 : // The matching release happens when the actor is destroyed, in
274 : // ContentChild::DeallocPFlyWebPublishedServerChild
275 0 : NS_ADDREF_THIS();
276 0 : }
277 :
278 : void
279 0 : FlyWebPublishedServerChild::PermissionGranted(bool aGranted)
280 : {
281 0 : if (!aGranted) {
282 0 : PublishedServerStarted(NS_ERROR_FAILURE);
283 0 : return;
284 : }
285 :
286 0 : mActorExists = true;
287 0 : FlyWebPublishOptions options;
288 0 : options.mUiUrl = mUiUrl;
289 :
290 : // Proceed with initialization.
291 0 : ContentChild::GetSingleton()->
292 0 : SendPFlyWebPublishedServerConstructor(this, mName, options);
293 : }
294 :
295 : mozilla::ipc::IPCResult
296 0 : FlyWebPublishedServerChild::RecvServerReady(const nsresult& aStatus)
297 : {
298 0 : LOG_I("FlyWebPublishedServerChild::RecvServerReady(%p)", this);
299 0 : MOZ_ASSERT(mActorExists);
300 :
301 0 : PublishedServerStarted(aStatus);
302 0 : return IPC_OK();
303 : }
304 :
305 : mozilla::ipc::IPCResult
306 0 : FlyWebPublishedServerChild::RecvServerClose()
307 : {
308 0 : LOG_I("FlyWebPublishedServerChild::RecvServerClose(%p)", this);
309 0 : MOZ_ASSERT(mActorExists);
310 :
311 0 : Close();
312 :
313 0 : return IPC_OK();
314 : }
315 :
316 : mozilla::ipc::IPCResult
317 0 : FlyWebPublishedServerChild::RecvFetchRequest(const IPCInternalRequest& aRequest,
318 : const uint64_t& aRequestId)
319 : {
320 0 : LOG_I("FlyWebPublishedServerChild::RecvFetchRequest(%p)", this);
321 0 : MOZ_ASSERT(mActorExists);
322 :
323 0 : RefPtr<InternalRequest> request = new InternalRequest(aRequest);
324 0 : mPendingRequests.Put(request, aRequestId);
325 0 : FireFetchEvent(request);
326 :
327 0 : return IPC_OK();
328 : }
329 :
330 : mozilla::ipc::IPCResult
331 0 : FlyWebPublishedServerChild::RecvWebSocketRequest(const IPCInternalRequest& aRequest,
332 : const uint64_t& aRequestId,
333 : PTransportProviderChild* aProvider)
334 : {
335 0 : LOG_I("FlyWebPublishedServerChild::RecvWebSocketRequest(%p)", this);
336 0 : MOZ_ASSERT(mActorExists);
337 :
338 0 : RefPtr<InternalRequest> request = new InternalRequest(aRequest);
339 0 : mPendingRequests.Put(request, aRequestId);
340 :
341 : // Not addreffing here. The addref was already done when the
342 : // PTransportProvider child constructor original ran.
343 0 : mPendingTransportProviders.Put(aRequestId,
344 0 : dont_AddRef(static_cast<TransportProviderChild*>(aProvider)));
345 :
346 0 : FireWebsocketEvent(request);
347 :
348 0 : return IPC_OK();
349 : }
350 :
351 : void
352 0 : FlyWebPublishedServerChild::ActorDestroy(ActorDestroyReason aWhy)
353 : {
354 0 : LOG_I("FlyWebPublishedServerChild::ActorDestroy(%p)", this);
355 :
356 0 : mActorExists = false;
357 0 : }
358 :
359 : void
360 0 : FlyWebPublishedServerChild::OnFetchResponse(InternalRequest* aRequest,
361 : InternalResponse* aResponse)
362 : {
363 0 : LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
364 :
365 0 : if (!mActorExists) {
366 0 : LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
367 0 : return;
368 : }
369 :
370 0 : uint64_t id = mPendingRequests.Get(aRequest);
371 0 : MOZ_ASSERT(id);
372 0 : mPendingRequests.Remove(aRequest);
373 :
374 0 : IPCInternalResponse ipcResp;
375 0 : UniquePtr<mozilla::ipc::AutoIPCStream> autoStream;
376 0 : nsIContentChild* cc = static_cast<ContentChild*>(Manager());
377 0 : aResponse->ToIPC(&ipcResp, cc, autoStream);
378 0 : Unused << SendFetchResponse(ipcResp, id);
379 0 : if (autoStream) {
380 0 : autoStream->TakeOptionalValue();
381 : }
382 : }
383 :
384 : already_AddRefed<nsITransportProvider>
385 0 : FlyWebPublishedServerChild::OnWebSocketAcceptInternal(InternalRequest* aRequest,
386 : const Optional<nsAString>& aProtocol,
387 : ErrorResult& aRv)
388 : {
389 0 : LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p)", this);
390 :
391 0 : if (!mActorExists) {
392 0 : LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p) - No actor!", this);
393 0 : return nullptr;
394 : }
395 :
396 0 : uint64_t id = mPendingRequests.Get(aRequest);
397 0 : MOZ_ASSERT(id);
398 0 : mPendingRequests.Remove(aRequest);
399 :
400 0 : RefPtr<TransportProviderChild> provider;
401 0 : mPendingTransportProviders.Remove(id, getter_AddRefs(provider));
402 :
403 0 : nsString protocol;
404 0 : if (aProtocol.WasPassed()) {
405 0 : protocol = aProtocol.Value();
406 :
407 0 : nsAutoCString reqProtocols;
408 : aRequest->Headers()->
409 0 : GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Protocol"), reqProtocols, aRv);
410 0 : if (!ContainsToken(reqProtocols, NS_ConvertUTF16toUTF8(protocol))) {
411 : // Should throw a better error here
412 0 : aRv.Throw(NS_ERROR_FAILURE);
413 0 : return nullptr;
414 : }
415 : } else {
416 0 : protocol.SetIsVoid(true);
417 : }
418 :
419 0 : Unused << SendWebSocketAccept(protocol, id);
420 :
421 0 : return provider.forget();
422 : }
423 :
424 : void
425 0 : FlyWebPublishedServerChild::OnWebSocketResponse(InternalRequest* aRequest,
426 : InternalResponse* aResponse)
427 : {
428 0 : LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
429 :
430 0 : if (!mActorExists) {
431 0 : LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
432 0 : return;
433 : }
434 :
435 0 : uint64_t id = mPendingRequests.Get(aRequest);
436 0 : MOZ_ASSERT(id);
437 0 : mPendingRequests.Remove(aRequest);
438 :
439 0 : mPendingTransportProviders.Remove(id);
440 :
441 0 : IPCInternalResponse ipcResp;
442 0 : UniquePtr<mozilla::ipc::AutoIPCStream> autoStream;
443 0 : nsIContentChild* cc = static_cast<ContentChild*>(Manager());
444 0 : aResponse->ToIPC(&ipcResp, cc, autoStream);
445 :
446 0 : Unused << SendWebSocketResponse(ipcResp, id);
447 0 : if (autoStream) {
448 0 : autoStream->TakeOptionalValue();
449 : }
450 : }
451 :
452 : void
453 0 : FlyWebPublishedServerChild::Close()
454 : {
455 0 : LOG_I("FlyWebPublishedServerChild::Close(%p)", this);
456 :
457 0 : FlyWebPublishedServer::Close();
458 :
459 0 : if (mActorExists) {
460 0 : LOG_I("FlyWebPublishedServerChild::Close - sending __delete__ (%p)", this);
461 :
462 0 : Send__delete__(this);
463 : }
464 0 : }
465 :
466 : /******** FlyWebPublishedServerParent ********/
467 :
468 0 : NS_IMPL_ISUPPORTS(FlyWebPublishedServerParent, nsIDOMEventListener)
469 :
470 0 : FlyWebPublishedServerParent::FlyWebPublishedServerParent(const nsAString& aName,
471 0 : const FlyWebPublishOptions& aOptions)
472 : : mActorDestroyed(false)
473 0 : , mNextRequestId(1)
474 : {
475 0 : LOG_I("FlyWebPublishedServerParent::FlyWebPublishedServerParent(%p)", this);
476 :
477 0 : RefPtr<FlyWebService> service = FlyWebService::GetOrCreate();
478 0 : if (!service) {
479 0 : Unused << SendServerReady(NS_ERROR_FAILURE);
480 0 : return;
481 : }
482 :
483 : RefPtr<FlyWebPublishPromise> mozPromise =
484 0 : service->PublishServer(aName, aOptions, nullptr);
485 0 : if (!mozPromise) {
486 0 : Unused << SendServerReady(NS_ERROR_FAILURE);
487 0 : return;
488 : }
489 :
490 0 : RefPtr<FlyWebPublishedServerParent> self = this;
491 :
492 : mozPromise->Then(
493 : // Non DocGroup-version for the task in parent.
494 : GetMainThreadSerialEventTarget(),
495 : __func__,
496 0 : [this, self] (FlyWebPublishedServer* aServer) {
497 0 : mPublishedServer = static_cast<FlyWebPublishedServerImpl*>(aServer);
498 0 : if (mActorDestroyed) {
499 0 : mPublishedServer->Close();
500 0 : return;
501 : }
502 :
503 0 : mPublishedServer->AddEventListener(NS_LITERAL_STRING("fetch"),
504 0 : this, false, false, 2);
505 0 : mPublishedServer->AddEventListener(NS_LITERAL_STRING("websocket"),
506 0 : this, false, false, 2);
507 0 : mPublishedServer->AddEventListener(NS_LITERAL_STRING("close"),
508 0 : this, false, false, 2);
509 0 : Unused << SendServerReady(NS_OK);
510 : },
511 0 : [this, self] (nsresult aStatus) {
512 0 : MOZ_ASSERT(NS_FAILED(aStatus));
513 0 : if (!mActorDestroyed) {
514 0 : Unused << SendServerReady(aStatus);
515 : }
516 0 : });
517 : }
518 :
519 : NS_IMETHODIMP
520 0 : FlyWebPublishedServerParent::HandleEvent(nsIDOMEvent* aEvent)
521 : {
522 0 : if (mActorDestroyed) {
523 0 : return NS_OK;
524 : }
525 :
526 0 : nsAutoString type;
527 0 : aEvent->GetType(type);
528 0 : if (type.EqualsLiteral("close")) {
529 0 : Unused << SendServerClose();
530 0 : return NS_OK;
531 : }
532 :
533 0 : if (type.EqualsLiteral("fetch")) {
534 : RefPtr<InternalRequest> request =
535 0 : static_cast<FlyWebFetchEvent*>(aEvent)->Request()->GetInternalRequest();
536 0 : uint64_t id = mNextRequestId++;
537 0 : mPendingRequests.Put(id, request);
538 :
539 0 : IPCInternalRequest ipcReq;
540 0 : request->ToIPC(&ipcReq);
541 0 : Unused << SendFetchRequest(ipcReq, id);
542 0 : return NS_OK;
543 : }
544 :
545 0 : if (type.EqualsLiteral("websocket")) {
546 : RefPtr<InternalRequest> request =
547 0 : static_cast<FlyWebWebSocketEvent*>(aEvent)->Request()->GetInternalRequest();
548 0 : uint64_t id = mNextRequestId++;
549 0 : mPendingRequests.Put(id, request);
550 :
551 0 : nsTArray<PNeckoParent*> neckoParents;
552 0 : Manager()->ManagedPNeckoParent(neckoParents);
553 0 : if (neckoParents.Length() != 1) {
554 0 : MOZ_CRASH("Expected exactly 1 PNeckoParent instance per PNeckoChild");
555 : }
556 :
557 : RefPtr<TransportProviderParent> provider =
558 : static_cast<TransportProviderParent*>(
559 0 : neckoParents[0]->SendPTransportProviderConstructor());
560 :
561 0 : IPCInternalRequest ipcReq;
562 0 : request->ToIPC(&ipcReq);
563 0 : Unused << SendWebSocketRequest(ipcReq, id, provider);
564 :
565 0 : mPendingTransportProviders.Put(id, provider.forget());
566 0 : return NS_OK;
567 : }
568 :
569 0 : MOZ_CRASH("Unknown event type");
570 :
571 : return NS_OK;
572 : }
573 :
574 : mozilla::ipc::IPCResult
575 0 : FlyWebPublishedServerParent::RecvFetchResponse(const IPCInternalResponse& aResponse,
576 : const uint64_t& aRequestId)
577 : {
578 0 : MOZ_ASSERT(!mActorDestroyed);
579 :
580 0 : RefPtr<InternalRequest> request;
581 0 : mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
582 0 : if (!request) {
583 0 : static_cast<ContentParent*>(Manager())->KillHard("unknown request id");
584 0 : return IPC_FAIL_NO_REASON(this);
585 : }
586 :
587 0 : RefPtr<InternalResponse> response = InternalResponse::FromIPC(aResponse);
588 :
589 0 : mPublishedServer->OnFetchResponse(request, response);
590 :
591 0 : return IPC_OK();
592 : }
593 :
594 : mozilla::ipc::IPCResult
595 0 : FlyWebPublishedServerParent::RecvWebSocketResponse(const IPCInternalResponse& aResponse,
596 : const uint64_t& aRequestId)
597 : {
598 0 : MOZ_ASSERT(!mActorDestroyed);
599 :
600 0 : mPendingTransportProviders.Remove(aRequestId);
601 :
602 0 : RefPtr<InternalRequest> request;
603 0 : mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
604 0 : if (!request) {
605 0 : static_cast<ContentParent*>(Manager())->KillHard("unknown websocket request id");
606 0 : return IPC_FAIL_NO_REASON(this);
607 : }
608 :
609 0 : RefPtr<InternalResponse> response = InternalResponse::FromIPC(aResponse);
610 :
611 0 : mPublishedServer->OnWebSocketResponse(request, response);
612 :
613 0 : return IPC_OK();
614 : }
615 :
616 : mozilla::ipc::IPCResult
617 0 : FlyWebPublishedServerParent::RecvWebSocketAccept(const nsString& aProtocol,
618 : const uint64_t& aRequestId)
619 : {
620 0 : MOZ_ASSERT(!mActorDestroyed);
621 :
622 0 : RefPtr<TransportProviderParent> providerIPC;
623 0 : mPendingTransportProviders.Remove(aRequestId, getter_AddRefs(providerIPC));
624 :
625 0 : RefPtr<InternalRequest> request;
626 0 : mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
627 :
628 0 : if (!request || !providerIPC) {
629 0 : static_cast<ContentParent*>(Manager())->KillHard("unknown websocket request id");
630 0 : return IPC_FAIL_NO_REASON(this);
631 : }
632 :
633 0 : Optional<nsAString> protocol;
634 0 : if (!aProtocol.IsVoid()) {
635 0 : protocol = &aProtocol;
636 : }
637 :
638 0 : ErrorResult result;
639 : nsCOMPtr<nsITransportProvider> providerServer =
640 0 : mPublishedServer->OnWebSocketAcceptInternal(request, protocol, result);
641 0 : if (result.Failed()) {
642 0 : return IPC_FAIL_NO_REASON(this);
643 : }
644 :
645 0 : DebugOnly<nsresult> rv = providerServer->SetListener(providerIPC);
646 0 : MOZ_ASSERT(NS_SUCCEEDED(rv));
647 :
648 0 : return IPC_OK();
649 : }
650 :
651 : void
652 0 : FlyWebPublishedServerParent::ActorDestroy(ActorDestroyReason aWhy)
653 : {
654 0 : LOG_I("FlyWebPublishedServerParent::ActorDestroy(%p)", this);
655 :
656 0 : mActorDestroyed = true;
657 0 : }
658 :
659 : mozilla::ipc::IPCResult
660 0 : FlyWebPublishedServerParent::Recv__delete__()
661 : {
662 0 : LOG_I("FlyWebPublishedServerParent::Recv__delete__(%p)", this);
663 0 : MOZ_ASSERT(!mActorDestroyed);
664 :
665 0 : if (mPublishedServer) {
666 0 : mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("fetch"),
667 0 : this, false);
668 0 : mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("websocket"),
669 0 : this, false);
670 0 : mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("close"),
671 0 : this, false);
672 0 : mPublishedServer->Close();
673 0 : mPublishedServer = nullptr;
674 : }
675 0 : return IPC_OK();
676 : }
677 :
678 : } // namespace dom
679 : } // namespace mozilla
680 :
681 :
|