Bug 1263991 parts 2 and 2.5: Enable launching a server in the parent process. r=baku,ehsan
authorJonas Sicking <jonas@sicking.cc>
Tue, 07 Jun 2016 02:46:03 -0700
changeset 341021 c9cc418f871dba0a3cca29c6e4afbce7dba4670d
parent 341020 e26bfa28a8826bac045ce8f6c7bb99f4da1bccf8
child 341022 411ea82341038f2a4fbac62bb8ff1ce03e0628e2
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku, ehsan
bugs1263991
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1263991 parts 2 and 2.5: Enable launching a server in the parent process. r=baku,ehsan
dom/base/Navigator.cpp
dom/flyweb/FlyWebPublishOptionsIPCSerializer.h
dom/flyweb/FlyWebPublishedServer.cpp
dom/flyweb/FlyWebPublishedServer.h
dom/flyweb/FlyWebPublishedServerIPC.h
dom/flyweb/FlyWebService.cpp
dom/flyweb/FlyWebService.h
dom/flyweb/HttpServer.cpp
dom/flyweb/PFlyWebPublishedServer.ipdl
dom/flyweb/moz.build
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -32,16 +32,17 @@
 #include "mozilla/Preferences.h"
 #include "mozilla/Telemetry.h"
 #include "BatteryManager.h"
 #include "mozilla/dom/DeviceStorageAreaListener.h"
 #include "mozilla/dom/PowerManager.h"
 #include "mozilla/dom/WakeLock.h"
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/CellBroadcast.h"
+#include "mozilla/dom/FlyWebPublishedServer.h"
 #include "mozilla/dom/FlyWebService.h"
 #include "mozilla/dom/IccManager.h"
 #include "mozilla/dom/InputPortManager.h"
 #include "mozilla/dom/MobileMessageManager.h"
 #include "mozilla/dom/Permissions.h"
 #include "mozilla/dom/Presentation.h"
 #include "mozilla/dom/ServiceWorkerContainer.h"
 #include "mozilla/dom/TCPSocket.h"
@@ -1609,17 +1610,38 @@ Navigator::PublishServer(const nsAString
                          ErrorResult& aRv)
 {
   RefPtr<FlyWebService> service = FlyWebService::GetOrCreate();
   if (!service) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  return service->PublishServer(aName, aOptions, mWindow, aRv);
+  RefPtr<FlyWebPublishPromise> mozPromise =
+    service->PublishServer(aName, aOptions, mWindow);
+  MOZ_ASSERT(mozPromise);
+
+  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(mWindow);
+  ErrorResult result;
+  RefPtr<Promise> domPromise = Promise::Create(global, result);
+  if (result.Failed()) {
+    aRv.Throw(NS_ERROR_FAILURE);
+    return nullptr;
+  }
+
+  mozPromise->Then(AbstractThread::MainThread(),
+                   __func__,
+                   [domPromise] (FlyWebPublishedServer* aServer) {
+                     domPromise->MaybeResolve(aServer);
+                   },
+                   [domPromise] (nsresult aStatus) {
+                     domPromise->MaybeReject(aStatus);
+                   });
+
+  return domPromise.forget();
 }
 
 already_AddRefed<Promise>
 Navigator::GetFeature(const nsAString& aName, ErrorResult& aRv)
 {
   nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
   RefPtr<Promise> p = Promise::Create(go, aRv);
   if (aRv.Failed()) {
new file mode 100644
--- /dev/null
+++ b/dom/flyweb/FlyWebPublishOptionsIPCSerializer.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_FlyWebPublishOptionsIPCSerialiser_h
+#define mozilla_dom_FlyWebPublishOptionsIPCSerialiser_h
+
+#include "mozilla/dom/FlyWebPublishBinding.h"
+
+namespace IPC {
+
+template <>
+struct ParamTraits<mozilla::dom::FlyWebPublishOptions>
+{
+  typedef mozilla::dom::FlyWebPublishOptions paramType;
+
+  // Function to serialize a FlyWebPublishOptions
+  static void Write(Message *aMsg, const paramType& aParam)
+  {
+    WriteParam(aMsg, aParam.mUiUrl);
+  }
+  // Function to de-serialize a FlyWebPublishOptions
+  static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
+  {
+    return ReadParam(aMsg, aIter, &(aResult->mUiUrl));
+  }
+};
+
+}
+
+#endif // mozilla_dom_FlyWebPublishOptionsIPCSerialiser_h
--- a/dom/flyweb/FlyWebPublishedServer.cpp
+++ b/dom/flyweb/FlyWebPublishedServer.cpp
@@ -1,143 +1,177 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-#include "mozilla/dom/FlyWebPublishedServer.h"
+#include "mozilla/dom/FlyWebPublishedServerIPC.h"
 #include "mozilla/dom/FlyWebPublishBinding.h"
 #include "mozilla/dom/FlyWebService.h"
 #include "mozilla/dom/Request.h"
 #include "mozilla/dom/FlyWebServerEvents.h"
+#include "mozilla/dom/ContentChild.h"
+#include "mozilla/ErrorResult.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/unused.h"
 #include "nsGlobalWindow.h"
 
 namespace mozilla {
 namespace dom {
 
 static LazyLogModule gFlyWebPublishedServerLog("FlyWebPublishedServer");
 #undef LOG_I
 #define LOG_I(...) MOZ_LOG(mozilla::dom::gFlyWebPublishedServerLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
 #undef LOG_E
 #define LOG_E(...) MOZ_LOG(mozilla::dom::gFlyWebPublishedServerLog, mozilla::LogLevel::Error, (__VA_ARGS__))
 
-NS_IMPL_ISUPPORTS_INHERITED0(FlyWebPublishedServer, mozilla::DOMEventTargetHelper)
+/******** FlyWebPublishedServer ********/
 
 FlyWebPublishedServer::FlyWebPublishedServer(nsPIDOMWindowInner* aOwner,
                                              const nsAString& aName,
-                                             const FlyWebPublishOptions& aOptions,
-                                             Promise* aPublishPromise)
+                                             const FlyWebPublishOptions& aOptions)
   : mozilla::DOMEventTargetHelper(aOwner)
   , mOwnerWindowID(aOwner ? aOwner->WindowID() : 0)
-  , mPublishPromise(aPublishPromise)
   , mName(aName)
   , mUiUrl(aOptions.mUiUrl)
   , mIsRegistered(true) // Registered by the FlyWebService
 {
-  mHttpServer = new HttpServer();
-  mHttpServer->Init(-1, Preferences::GetBool("flyweb.use-tls", false), this);
 }
 
-FlyWebPublishedServer::~FlyWebPublishedServer()
+void
+FlyWebPublishedServer::LastRelease()
 {
-  // Make sure to unregister to avoid dangling pointers
+  // Make sure to unregister to avoid dangling pointers. Use the LastRelease
+  // hook rather than dtor since calling virtual functions during dtor
+  // wouldn't do what we want. Also, LastRelease is called earlier than dtor
+  // for CC objects.
   Close();
 }
 
 JSObject*
 FlyWebPublishedServer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return FlyWebPublishedServerBinding::Wrap(aCx, this, aGivenProto);
 }
 
 void
 FlyWebPublishedServer::Close()
 {
+  LOG_I("FlyWebPublishedServer::Close(%p)", this);
+
   // Unregister from server.
   if (mIsRegistered) {
-    FlyWebService::GetOrCreate()->UnregisterServer(this);
+    MOZ_ASSERT(FlyWebService::GetExisting());
+    FlyWebService::GetExisting()->UnregisterServer(this);
     mIsRegistered = false;
+
+    DispatchTrustedEvent(NS_LITERAL_STRING("close"));
   }
+}
+
+void
+FlyWebPublishedServer::FireFetchEvent(InternalRequest* aRequest)
+{
+  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
+  RefPtr<FlyWebFetchEvent> e = new FlyWebFetchEvent(this,
+                                                    new Request(global, aRequest),
+                                                    aRequest);
+  e->Init(this);
+  e->InitEvent(NS_LITERAL_STRING("fetch"), false, false);
+
+  DispatchTrustedEvent(e);
+}
+
+void
+FlyWebPublishedServer::FireWebsocketEvent(InternalRequest* aConnectRequest)
+{
+  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
+  RefPtr<FlyWebFetchEvent> e = new FlyWebWebSocketEvent(this,
+                                                        new Request(global, aConnectRequest),
+                                                        aConnectRequest);
+  e->Init(this);
+  e->InitEvent(NS_LITERAL_STRING("websocket"), false, false);
+
+  DispatchTrustedEvent(e);
+}
+
+void
+FlyWebPublishedServer::PublishedServerStarted(nsresult aStatus)
+{
+  LOG_I("FlyWebPublishedServer::PublishedServerStarted(%p)", this);
+
+  RefPtr<FlyWebPublishPromise> promise = mPublishPromise.Ensure(__func__);
+  if (NS_SUCCEEDED(aStatus)) {
+    mPublishPromise.Resolve(this, __func__);
+  } else {
+    Close();
+    mPublishPromise.Reject(aStatus, __func__);
+  }
+}
+
+/******** FlyWebPublishedServerImpl ********/
+
+NS_IMPL_ISUPPORTS_INHERITED0(FlyWebPublishedServerImpl, mozilla::DOMEventTargetHelper)
+
+FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(nsPIDOMWindowInner* aOwner,
+                                                     const nsAString& aName,
+                                                     const FlyWebPublishOptions& aOptions)
+  : FlyWebPublishedServer(aOwner, aName, aOptions)
+  , mHttpServer(new HttpServer())
+{
+  LOG_I("FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(%p)", this);
+
+  mHttpServer->Init(-1, Preferences::GetBool("flyweb.use-tls", false), this);
+}
+
+void
+FlyWebPublishedServerImpl::Close()
+{
+  FlyWebPublishedServer::Close();
 
   if (mMDNSCancelRegister) {
     mMDNSCancelRegister->Cancel(NS_BINDING_ABORTED);
     mMDNSCancelRegister = nullptr;
   }
 
   if (mHttpServer) {
     RefPtr<HttpServer> server = mHttpServer.forget();
     server->Close();
   }
 }
 
 void
-FlyWebPublishedServer::OnServerStarted(nsresult aStatus)
+FlyWebPublishedServerImpl::OnServerStarted(nsresult aStatus)
 {
   if (NS_SUCCEEDED(aStatus)) {
     FlyWebService::GetOrCreate()->StartDiscoveryOf(this);
   } else {
-    DiscoveryStarted(aStatus);
+    PublishedServerStarted(aStatus);
   }
 }
 
 void
-FlyWebPublishedServer::OnServerClose()
-{
-  mHttpServer = nullptr;
-  Close();
-
-  DispatchTrustedEvent(NS_LITERAL_STRING("close"));
-}
-
-void
-FlyWebPublishedServer::OnRequest(InternalRequest* aRequest)
-{
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
-  RefPtr<FlyWebFetchEvent> e = new FlyWebFetchEvent(this,
-                                                    new Request(global, aRequest),
-                                                    aRequest);
-  e->Init(this);
-  e->InitEvent(NS_LITERAL_STRING("fetch"), false, false);
-
-  DispatchTrustedEvent(e);
-}
-
-void
-FlyWebPublishedServer::OnWebSocket(InternalRequest* aConnectRequest)
-{
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
-  RefPtr<FlyWebFetchEvent> e = new FlyWebWebSocketEvent(this,
-                                                        new Request(global, aConnectRequest),
-                                                        aConnectRequest);
-  e->Init(this);
-  e->InitEvent(NS_LITERAL_STRING("websocket"), false, false);
-
-  DispatchTrustedEvent(e);
-}
-
-void
-FlyWebPublishedServer::OnFetchResponse(InternalRequest* aRequest,
-                                       InternalResponse* aResponse)
+FlyWebPublishedServerImpl::OnFetchResponse(InternalRequest* aRequest,
+                                           InternalResponse* aResponse)
 {
   MOZ_ASSERT(aRequest);
   MOZ_ASSERT(aResponse);
 
-  LOG_I("FlyWebPublishedMDNSServer::OnFetchResponse(%p)", this);
+  LOG_I("FlyWebPublishedServerImpl::OnFetchResponse(%p)", this);
 
   if (mHttpServer) {
     mHttpServer->SendResponse(aRequest, aResponse);
   }
 }
 
 already_AddRefed<WebSocket>
-FlyWebPublishedServer::OnWebSocketAccept(InternalRequest* aConnectRequest,
-                                         const Optional<nsAString>& aProtocol,
-                                         ErrorResult& aRv)
+FlyWebPublishedServerImpl::OnWebSocketAccept(InternalRequest* aConnectRequest,
+                                             const Optional<nsAString>& aProtocol,
+                                             ErrorResult& aRv)
 {
   MOZ_ASSERT(aConnectRequest);
 
   LOG_I("FlyWebPublishedMDNSServer::OnWebSocketAccept(%p)", this);
 
   if (!mHttpServer) {
     aRv.Throw(NS_ERROR_UNEXPECTED);
     return nullptr;
@@ -171,35 +205,167 @@ FlyWebPublishedServer::OnWebSocketAccept
                                       NS_ConvertUTF8toUTF16(url),
                                       protocols,
                                       provider,
                                       negotiatedExtensions,
                                       aRv);
 }
 
 void
-FlyWebPublishedServer::OnWebSocketResponse(InternalRequest* aConnectRequest,
-                                           InternalResponse* aResponse)
+FlyWebPublishedServerImpl::OnWebSocketResponse(InternalRequest* aConnectRequest,
+                                               InternalResponse* aResponse)
 {
   MOZ_ASSERT(aConnectRequest);
   MOZ_ASSERT(aResponse);
 
   LOG_I("FlyWebPublishedMDNSServer::OnWebSocketResponse(%p)", this);
 
   if (mHttpServer) {
     mHttpServer->SendWebSocketResponse(aConnectRequest, aResponse);
   }
 }
 
-void FlyWebPublishedServer::DiscoveryStarted(nsresult aStatus)
+/******** FlyWebPublishedServerChild ********/
+
+FlyWebPublishedServerChild::FlyWebPublishedServerChild(nsPIDOMWindowInner* aOwner,
+                                                       const nsAString& aName,
+                                                       const FlyWebPublishOptions& aOptions)
+  : FlyWebPublishedServer(aOwner, aName, aOptions)
+  , mActorDestroyed(false)
+{
+  LOG_I("FlyWebPublishedServerChild::FlyWebPublishedServerChild(%p)", this);
+
+  ContentChild::GetSingleton()->
+    SendPFlyWebPublishedServerConstructor(this,
+                                          PromiseFlatString(aName),
+                                          aOptions);
+
+  // The matching release happens when the actor is destroyed, in
+  // ContentChild::DeallocPFlyWebPublishedServerChild
+  NS_ADDREF_THIS();
+}
+
+bool
+FlyWebPublishedServerChild::RecvServerReady(const nsresult& aStatus)
+{
+  LOG_I("FlyWebPublishedServerChild::RecvServerReady(%p)", this);
+
+  PublishedServerStarted(aStatus);
+  return true;
+}
+
+bool
+FlyWebPublishedServerChild::RecvServerClose()
+{
+  LOG_I("FlyWebPublishedServerChild::RecvServerClose(%p)", this);
+
+  Close();
+
+  return true;
+}
+
+void
+FlyWebPublishedServerChild::ActorDestroy(ActorDestroyReason aWhy)
+{
+  LOG_I("FlyWebPublishedServerChild::ActorDestroy(%p)", this);
+
+  mActorDestroyed = true;
+}
+
+void
+FlyWebPublishedServerChild::OnFetchResponse(InternalRequest* aRequest,
+                                            InternalResponse* aResponse)
+{
+  // Send ipdl message to parent
+}
+
+already_AddRefed<WebSocket>
+FlyWebPublishedServerChild::OnWebSocketAccept(InternalRequest* aConnectRequest,
+                                              const Optional<nsAString>& aProtocol,
+                                              ErrorResult& aRv)
+{
+  // Send ipdl message to parent
+  return nullptr;
+}
+
+void
+FlyWebPublishedServerChild::OnWebSocketResponse(InternalRequest* aConnectRequest,
+                                                InternalResponse* aResponse)
 {
-  if (NS_SUCCEEDED(aStatus)) {
-    mPublishPromise->MaybeResolve(this);
-  } else {
-    Close();
-    mPublishPromise->MaybeReject(aStatus);
+  // Send ipdl message to parent
+}
+
+void
+FlyWebPublishedServerChild::Close()
+{
+  LOG_I("FlyWebPublishedServerChild::Close(%p)", this);
+
+  FlyWebPublishedServer::Close();
+
+  if (!mActorDestroyed) {
+    LOG_I("FlyWebPublishedServerChild::Close - sending __delete__ (%p)", this);
+
+    Send__delete__(this);
+  }
+}
+
+/******** FlyWebPublishedServerParent ********/
+
+FlyWebPublishedServerParent::FlyWebPublishedServerParent(const nsAString& aName,
+                                                         const FlyWebPublishOptions& aOptions)
+  : mActorDestroyed(false)
+{
+  LOG_I("FlyWebPublishedServerParent::FlyWebPublishedServerParent(%p)", this);
+
+  RefPtr<FlyWebService> service = FlyWebService::GetOrCreate();
+  if (!service) {
+    Unused << SendServerReady(NS_ERROR_FAILURE);
+    return;
+  }
+
+  RefPtr<FlyWebPublishPromise> mozPromise =
+    service->PublishServer(aName, aOptions, nullptr);
+  if (!mozPromise) {
+    Unused << SendServerReady(NS_ERROR_FAILURE);
+    return;
   }
+
+  RefPtr<FlyWebPublishedServerParent> self = this;
+
+  mozPromise->Then(AbstractThread::MainThread(),
+                   __func__,
+                   [this, self] (FlyWebPublishedServer* aServer) {
+                     mPublishedServer = static_cast<FlyWebPublishedServerImpl*>(aServer);
+                     if (!mActorDestroyed) {
+                       Unused << SendServerReady(NS_OK);
+                     }
+                   },
+                   [this, self] (nsresult aStatus) {
+                     if (!mActorDestroyed) {
+                       Unused << SendServerReady(aStatus);
+                     }
+                   });
+}
+
+void
+FlyWebPublishedServerParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+  LOG_I("FlyWebPublishedServerParent::ActorDestroy(%p)", this);
+
+  mActorDestroyed = true;
+}
+
+bool
+FlyWebPublishedServerParent::Recv__delete__()
+{
+  LOG_I("FlyWebPublishedServerParent::Recv__delete__(%p)", this);
+
+  if (mPublishedServer) {
+    mPublishedServer->Close();
+    mPublishedServer = nullptr;
+  }
+  return true;
 }
 
 } // namespace dom
 } // namespace mozilla
 
 
--- a/dom/flyweb/FlyWebPublishedServer.h
+++ b/dom/flyweb/FlyWebPublishedServer.h
@@ -2,112 +2,99 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_FlyWebPublishedServer_h
 #define mozilla_dom_FlyWebPublishedServer_h
 
-#include "nsISupportsImpl.h"
-#include "nsICancelable.h"
 #include "mozilla/DOMEventTargetHelper.h"
-#include "mozilla/ErrorResult.h"
-#include "HttpServer.h"
-#include "mozilla/dom/WebSocket.h"
+#include "mozilla/MozPromise.h"
 
 class nsPIDOMWindowInner;
 
 namespace mozilla {
+
+class ErrorResult;
+
 namespace dom {
 
-class Promise;
 class InternalResponse;
 class InternalRequest;
+class WebSocket;
 struct FlyWebPublishOptions;
 class FlyWebPublishedServer;
 
-class FlyWebPublishedServer final : public mozilla::DOMEventTargetHelper
-                                  , public HttpServerListener
+typedef MozPromise<RefPtr<FlyWebPublishedServer>, nsresult, false>
+  FlyWebPublishPromise;
+
+class FlyWebPublishedServer : public mozilla::DOMEventTargetHelper
 {
 public:
   FlyWebPublishedServer(nsPIDOMWindowInner* aOwner,
                         const nsAString& aName,
-                        const FlyWebPublishOptions& aOptions,
-                        Promise* aPublishPromise);
+                        const FlyWebPublishOptions& aOptions);
+
+  virtual void LastRelease() override;
 
   virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
 
-  NS_DECL_ISUPPORTS_INHERITED
-
   uint64_t OwnerWindowID() const {
     return mOwnerWindowID;
   }
 
-  int32_t Port()
-  {
-    return mHttpServer ? mHttpServer->GetPort() : 0;
-  }
-  void GetCertKey(nsACString& aKey) {
-    if (mHttpServer) {
-      mHttpServer->GetCertKey(aKey);
-    } else {
-      aKey.Truncate();
-    }
-  }
-
   void GetName(nsAString& aName)
   {
     aName = mName;
   }
   nsAString& Name()
   {
     return mName;
   }
 
   void GetUiUrl(nsAString& aUiUrl)
   {
     aUiUrl = mUiUrl;
   }
 
-  void OnFetchResponse(InternalRequest* aRequest,
-                       InternalResponse* aResponse);
-  already_AddRefed<WebSocket>
+  virtual void OnFetchResponse(InternalRequest* aRequest,
+                               InternalResponse* aResponse) = 0;
+  virtual already_AddRefed<WebSocket>
     OnWebSocketAccept(InternalRequest* aConnectRequest,
                       const Optional<nsAString>& aProtocol,
-                      ErrorResult& aRv);
-  void OnWebSocketResponse(InternalRequest* aConnectRequest,
-                           InternalResponse* aResponse);
+                      ErrorResult& aRv) = 0;
+  virtual void OnWebSocketResponse(InternalRequest* aConnectRequest,
+                                   InternalResponse* aResponse) = 0;
 
-  void SetCancelRegister(nsICancelable* aCancelRegister)
-  {
-    mMDNSCancelRegister = aCancelRegister;
-  }
+  virtual void Close();
 
-  void Close();
-
-  // HttpServerListener
-  virtual void OnServerStarted(nsresult aStatus) override;
-  virtual void OnRequest(InternalRequest* aRequest) override;
-  virtual void OnWebSocket(InternalRequest* aConnectRequest) override;
-  virtual void OnServerClose() override;
+  void FireFetchEvent(InternalRequest* aRequest);
+  void FireWebsocketEvent(InternalRequest* aConnectRequest);
+  void PublishedServerStarted(nsresult aStatus);
 
   IMPL_EVENT_HANDLER(fetch)
   IMPL_EVENT_HANDLER(websocket)
   IMPL_EVENT_HANDLER(close)
 
-  void DiscoveryStarted(nsresult aStatus);
+  already_AddRefed<FlyWebPublishPromise>
+  GetPublishPromise()
+  {
+    return mPublishPromise.Ensure(__func__);
+  }
 
-private:
-  ~FlyWebPublishedServer();
+protected:
+
+  virtual ~FlyWebPublishedServer()
+  {
+    MOZ_ASSERT(!mIsRegistered, "Subclass dtor forgot to call Close()");
+  }
 
   uint64_t mOwnerWindowID;
-  RefPtr<HttpServer> mHttpServer;
-  RefPtr<Promise> mPublishPromise;
-  nsCOMPtr<nsICancelable> mMDNSCancelRegister;
+  MozPromiseHolder<FlyWebPublishPromise> mPublishPromise;
 
   nsString mName;
   nsString mUiUrl;
 
   bool mIsRegistered;
 };
 
 } // namespace dom
new file mode 100644
--- /dev/null
+++ b/dom/flyweb/FlyWebPublishedServerIPC.h
@@ -0,0 +1,141 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_FlyWebPublishedServerIPC_h
+#define mozilla_dom_FlyWebPublishedServerIPC_h
+
+#include "HttpServer.h"
+#include "mozilla/dom/FlyWebPublishedServer.h"
+#include "mozilla/dom/PFlyWebPublishedServerParent.h"
+#include "mozilla/dom/PFlyWebPublishedServerChild.h"
+#include "mozilla/MozPromise.h"
+#include "nsISupportsImpl.h"
+#include "nsICancelable.h"
+
+class nsPIDOMWindowInner;
+
+namespace mozilla {
+namespace dom {
+
+class FlyWebPublishedServerParent;
+
+class FlyWebPublishedServerImpl final : public FlyWebPublishedServer
+                                      , public HttpServerListener
+{
+public:
+  FlyWebPublishedServerImpl(nsPIDOMWindowInner* aOwner,
+                            const nsAString& aName,
+                            const FlyWebPublishOptions& aOptions);
+
+  NS_DECL_ISUPPORTS_INHERITED
+
+  int32_t Port()
+  {
+    return mHttpServer ? mHttpServer->GetPort() : 0;
+  }
+  void GetCertKey(nsACString& aKey) {
+    if (mHttpServer) {
+      mHttpServer->GetCertKey(aKey);
+    } else {
+      aKey.Truncate();
+    }
+  }
+
+  virtual void OnFetchResponse(InternalRequest* aRequest,
+                               InternalResponse* aResponse) override;
+  virtual already_AddRefed<WebSocket>
+    OnWebSocketAccept(InternalRequest* aConnectRequest,
+                      const Optional<nsAString>& aProtocol,
+                      ErrorResult& aRv) override;
+  virtual void OnWebSocketResponse(InternalRequest* aConnectRequest,
+                                   InternalResponse* aResponse) override;
+
+  void SetCancelRegister(nsICancelable* aCancelRegister)
+  {
+    mMDNSCancelRegister = aCancelRegister;
+  }
+
+  virtual void Close() override;
+
+  // HttpServerListener
+  virtual void OnServerStarted(nsresult aStatus) override;
+  virtual void OnRequest(InternalRequest* aRequest) override
+  {
+    FireFetchEvent(aRequest);
+  }
+  virtual void OnWebSocket(InternalRequest* aConnectRequest) override
+  {
+    FireWebsocketEvent(aConnectRequest);
+  }
+  virtual void OnServerClose() override
+  {
+    mHttpServer = nullptr;
+    Close();
+  }
+
+private:
+  ~FlyWebPublishedServerImpl() {}
+
+  RefPtr<HttpServer> mHttpServer;
+  nsCOMPtr<nsICancelable> mMDNSCancelRegister;
+  RefPtr<FlyWebPublishedServerParent> mServerParent;
+};
+
+class FlyWebPublishedServerChild final : public FlyWebPublishedServer
+                                       , public PFlyWebPublishedServerChild
+{
+public:
+  FlyWebPublishedServerChild(nsPIDOMWindowInner* aOwner,
+                             const nsAString& aName,
+                             const FlyWebPublishOptions& aOptions);
+
+  virtual bool RecvServerReady(const nsresult& aStatus) override;
+  virtual bool RecvServerClose() override;
+
+  virtual void OnFetchResponse(InternalRequest* aRequest,
+                               InternalResponse* aResponse) override;
+  virtual already_AddRefed<WebSocket>
+    OnWebSocketAccept(InternalRequest* aConnectRequest,
+                      const Optional<nsAString>& aProtocol,
+                      ErrorResult& aRv) override;
+  virtual void OnWebSocketResponse(InternalRequest* aConnectRequest,
+                                   InternalResponse* aResponse) override;
+
+  virtual void Close() override;
+
+  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
+
+private:
+  ~FlyWebPublishedServerChild() {}
+
+  bool mActorDestroyed;
+};
+
+class FlyWebPublishedServerParent final : public PFlyWebPublishedServerParent
+{
+public:
+  FlyWebPublishedServerParent(const nsAString& aName,
+                              const FlyWebPublishOptions& aOptions);
+
+  NS_INLINE_DECL_REFCOUNTING(FlyWebPublishedServerParent)
+
+private:
+  virtual void
+  ActorDestroy(ActorDestroyReason aWhy) override;
+
+  virtual bool
+  Recv__delete__() override;
+
+  ~FlyWebPublishedServerParent() {}
+
+  bool mActorDestroyed;
+  RefPtr<FlyWebPublishedServerImpl> mPublishedServer;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_FlyWebPublishedServerIPC_h
--- a/dom/flyweb/FlyWebService.cpp
+++ b/dom/flyweb/FlyWebService.cpp
@@ -3,17 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/FlyWebService.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/ScopeExit.h"
 #include "mozilla/dom/Promise.h"
-#include "mozilla/dom/FlyWebPublishedServer.h"
+#include "mozilla/dom/FlyWebPublishedServerIPC.h"
 #include "nsISocketTransportService.h"
 #include "mdns/libmdns/nsDNSServiceInfo.h"
 #include "nsIUUIDGenerator.h"
 #include "nsStandardURL.h"
 #include "mozilla/Services.h"
 #include "nsISupportsPrimitives.h"
 #include "mozilla/dom/FlyWebDiscoveryManagerBinding.h"
 #include "prnetdb.h"
@@ -72,17 +72,17 @@ private:
   nsresult StartDiscovery();
   nsresult StopDiscovery();
 
   void ListDiscoveredServices(nsTArray<FlyWebDiscoveredService>& aServices);
   bool HasService(const nsAString& aServiceId);
   nsresult PairWithService(const nsAString& aServiceId,
                            UniquePtr<FlyWebService::PairedInfo>& aInfo);
 
-  nsresult StartDiscoveryOf(FlyWebPublishedServer* aServer);
+  nsresult StartDiscoveryOf(FlyWebPublishedServerImpl* aServer);
 
   void EnsureDiscoveryStarted();
   void EnsureDiscoveryStopped();
 
   // Cycle-breaking link to manager.
   FlyWebService* mService;
   nsCString mServiceType;
 
@@ -437,17 +437,17 @@ FlyWebMDNSService::OnServiceRegistered(n
 
   nsString name = NS_ConvertUTF8toUTF16(cName);
   RefPtr<FlyWebPublishedServer> existingServer =
     FlyWebService::GetOrCreate()->FindPublishedServerByName(name);
   if (!existingServer) {
     return NS_ERROR_FAILURE;
   }
 
-  existingServer->DiscoveryStarted(NS_OK);
+  existingServer->PublishedServerStarted(NS_OK);
 
   return NS_OK;
 }
 
 nsresult
 FlyWebMDNSService::OnServiceUnregistered(nsIDNSServiceInfo* aServiceInfo)
 {
   LogDNSInfo(aServiceInfo, "FlyWebMDNSService::OnServiceUnregistered");
@@ -484,17 +484,17 @@ FlyWebMDNSService::OnRegistrationFailed(
     FlyWebService::GetOrCreate()->FindPublishedServerByName(name);
   if (!existingServer) {
     return NS_ERROR_FAILURE;
   }
 
   LOG_I("OnServiceRegistered(MDNS): Registration of server with name %s failed.", cName.get());
 
   // Remove the nsICancelable from the published server.
-  existingServer->DiscoveryStarted(NS_ERROR_FAILURE);
+  existingServer->PublishedServerStarted(NS_ERROR_FAILURE);
   return NS_OK;
 }
 
 nsresult
 FlyWebMDNSService::OnUnregistrationFailed(nsIDNSServiceInfo* aServiceInfo, int32_t errorCode)
 {
   LogDNSInfo(aServiceInfo, "FlyWebMDNSService::OnUnregistrationFailed");
 
@@ -691,17 +691,17 @@ FlyWebMDNSService::PairWithService(const
 
   aInfo->mService.mDiscoveredService = discInfo->mService;
   aInfo->mDNSServiceInfo = discInfo->mDNSServiceInfo;
 
   return NS_OK;
 }
 
 nsresult
-FlyWebMDNSService::StartDiscoveryOf(FlyWebPublishedServer* aServer)
+FlyWebMDNSService::StartDiscoveryOf(FlyWebPublishedServerImpl* aServer)
 {
 
   RefPtr<FlyWebPublishedServer> existingServer =
     FlyWebService::GetOrCreate()->FindPublishedServerByName(aServer->Name());
   MOZ_ASSERT(existingServer);
 
   // Advertise the service via mdns.
   RefPtr<net::nsDNSServiceInfo> serviceInfo(new net::nsDNSServiceInfo());
@@ -800,16 +800,24 @@ FlyWebService::GetOrCreate()
     }
   }
   return gFlyWebService;
 }
 
 ErrorResult
 FlyWebService::Init()
 {
+  // Most functions of FlyWebService should not be started in the child.
+  // Instead FlyWebService in the child is mainly responsible for tracking
+  // publishedServer lifetimes. Other functions are handled by the
+  // FlyWebService running in the parent.
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    return ErrorResult(NS_OK);
+  }
+
   MOZ_ASSERT(NS_IsMainThread());
   if (!mMDNSHttpService) {
     mMDNSHttpService = new FlyWebMDNSService(this, NS_LITERAL_CSTRING("_http._tcp."));
     ErrorResult rv;
 
     rv = mMDNSHttpService->Init();
     if (rv.Failed()) {
       LOG_E("FlyWebService failed to initialize MDNS _http._tcp.");
@@ -828,46 +836,44 @@ FlyWebService::Init()
       mMDNSFlywebService = nullptr;
       rv.SuppressException();
     }
   }
 
   return ErrorResult(NS_OK);
 }
 
-already_AddRefed<Promise>
+already_AddRefed<FlyWebPublishPromise>
 FlyWebService::PublishServer(const nsAString& aName,
                              const FlyWebPublishOptions& aOptions,
-                             nsPIDOMWindowInner* aWindow,
-                             ErrorResult& aRv)
+                             nsPIDOMWindowInner* aWindow)
 {
-  MOZ_ASSERT(NS_IsMainThread());
-  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aWindow);
-  RefPtr<Promise> promise = Promise::Create(global, aRv);
-  if (aRv.Failed()) {
-    return nullptr;
-  }
-
   // Scan uiUrl for illegal characters
 
   RefPtr<FlyWebPublishedServer> existingServer =
     FlyWebService::GetOrCreate()->FindPublishedServerByName(aName);
   if (existingServer) {
     LOG_I("PublishServer: Trying to publish server with already-existing name %s.",
           NS_ConvertUTF16toUTF8(aName).get());
-    promise->MaybeReject(NS_ERROR_FAILURE);
+    MozPromiseHolder<FlyWebPublishPromise> holder;
+    RefPtr<FlyWebPublishPromise> promise = holder.Ensure(__func__);
+    holder.Reject(NS_ERROR_FAILURE, __func__);
     return promise.forget();
   }
 
-  RefPtr<FlyWebPublishedServer> server =
-    new FlyWebPublishedServer(aWindow, aName, aOptions, promise);
+  RefPtr<FlyWebPublishedServer> server;
+  if (XRE_GetProcessType() == GeckoProcessType_Content) {
+    server = new FlyWebPublishedServerChild(aWindow, aName, aOptions);
+  } else {
+    server = new FlyWebPublishedServerImpl(aWindow, aName, aOptions);
+  }
 
   mServers.AppendElement(server);
 
-  return promise.forget();
+  return server->GetPublishPromise();
 }
 
 already_AddRefed<FlyWebPublishedServer>
 FlyWebService::FindPublishedServerByName(
         const nsAString& aName)
 {
   MOZ_ASSERT(NS_IsMainThread());
   for (FlyWebPublishedServer* publishedServer : mServers) {
@@ -1106,22 +1112,22 @@ FlyWebService::CreateTransportForHost(co
     types, typeCount, host, port, hostRoute, portRoute, proxyInfo, &netAddr);
   NS_ENSURE_SUCCESS(rv, rv);
 
   trans.forget(result);
   return NS_OK;
 }
 
 void
-FlyWebService::StartDiscoveryOf(FlyWebPublishedServer* aServer)
+FlyWebService::StartDiscoveryOf(FlyWebPublishedServerImpl* aServer)
 {
   MOZ_ASSERT(NS_IsMainThread());
   nsresult rv = mMDNSFlywebService ?
     mMDNSFlywebService->StartDiscoveryOf(aServer) :
     NS_ERROR_FAILURE;
 
   if (NS_FAILED(rv)) {
-    aServer->DiscoveryStarted(rv);
+    aServer->PublishedServerStarted(rv);
   }
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/flyweb/FlyWebService.h
+++ b/dom/flyweb/FlyWebService.h
@@ -8,55 +8,59 @@
 #define mozilla_dom_FlyWebService_h
 
 #include "nsISupportsImpl.h"
 #include "mozilla/ErrorResult.h"
 #include "nsIProtocolHandler.h"
 #include "nsDataHashtable.h"
 #include "nsClassHashtable.h"
 #include "nsIObserver.h"
+#include "mozilla/MozPromise.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/dom/FlyWebDiscoveryManagerBinding.h"
 #include "nsITimer.h"
 #include "nsICancelable.h"
 #include "nsIDNSServiceDiscovery.h"
 
 class nsPIDOMWindowInner;
 class nsIProxyInfo;
 class nsISocketTransport;
 
 namespace mozilla {
 namespace dom {
 
-class Promise;
 struct FlyWebPublishOptions;
 struct FlyWebFilter;
 class FlyWebPublishedServer;
+class FlyWebPublishedServerImpl;
 class FlyWebPairingCallback;
 class FlyWebDiscoveryManager;
 class FlyWebMDNSService;
 
+typedef MozPromise<RefPtr<FlyWebPublishedServer>, nsresult, false>
+  FlyWebPublishPromise;
+
 class FlyWebService final : public nsIObserver
 {
   friend class FlyWebMDNSService;
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   static FlyWebService* GetExisting();
   static FlyWebService* GetOrCreate();
   static already_AddRefed<FlyWebService> GetOrCreateAddRefed()
   {
     return do_AddRef(GetOrCreate());
   }
 
-  already_AddRefed<Promise> PublishServer(const nsAString& aName,
-                                          const FlyWebPublishOptions& aOptions,
-                                          nsPIDOMWindowInner* aWindow,
-                                          ErrorResult& aRv);
+  already_AddRefed<FlyWebPublishPromise>
+    PublishServer(const nsAString& aName,
+                  const FlyWebPublishOptions& aOptions,
+                  nsPIDOMWindowInner* aWindow);
 
   void UnregisterServer(FlyWebPublishedServer* aServer);
 
   bool HasConnectionOrServer(uint64_t aWindowID);
 
   void ListDiscoveredServices(nsTArray<FlyWebDiscoveredService>& aServices);
   void PairWithService(const nsAString& aServiceId, FlyWebPairingCallback& aCallback);
   nsresult CreateTransportForHost(const char **types,
@@ -69,18 +73,18 @@ public:
                                   nsISocketTransport **result);
 
   already_AddRefed<FlyWebPublishedServer> FindPublishedServerByName(
             const nsAString& aName);
 
   void RegisterDiscoveryManager(FlyWebDiscoveryManager* aDiscoveryManager);
   void UnregisterDiscoveryManager(FlyWebDiscoveryManager* aDiscoveryManager);
 
-  // Should only be called by FlyWebPublishedServer
-  void StartDiscoveryOf(FlyWebPublishedServer* aServer);
+  // Should only be called by FlyWebPublishedServerImpl
+  void StartDiscoveryOf(FlyWebPublishedServerImpl* aServer);
 
 private:
   FlyWebService();
   ~FlyWebService();
 
   ErrorResult Init();
 
   void NotifyDiscoveredServicesChanged();
--- a/dom/flyweb/HttpServer.cpp
+++ b/dom/flyweb/HttpServer.cpp
@@ -216,18 +216,18 @@ void
 HttpServer::Close()
 {
   if (mServerSocket) {
     mServerSocket->Close();
     mServerSocket = nullptr;
   }
 
   if (mListener) {
-    mListener->OnServerClose();
-    mListener = nullptr;
+    RefPtr<HttpServerListener> listener = mListener.forget();
+    listener->OnServerClose();
   }
 
   for (Connection* conn : mConnections) {
     conn->Close();
   }
   mConnections.Clear();
 }
 
new file mode 100644
--- /dev/null
+++ b/dom/flyweb/PFlyWebPublishedServer.ipdl
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et ft=cpp : */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+include protocol PContent;
+
+namespace mozilla {
+namespace dom {
+
+async protocol PFlyWebPublishedServer
+{
+  manager PContent;
+
+child:
+  async ServerReady(nsresult aStatus);
+  async ServerClose();
+
+parent:
+  async __delete__();
+};
+
+} // namespace dom
+} // namespace mozilla
--- a/dom/flyweb/moz.build
+++ b/dom/flyweb/moz.build
@@ -2,35 +2,41 @@
 # vim: set filetype=python:
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 EXPORTS.mozilla.dom += [
     'FlyWebDiscoveryManager.h',
     'FlyWebPublishedServer.h',
+    'FlyWebPublishedServerIPC.h',
+    'FlyWebPublishOptionsIPCSerializer.h',
     'FlyWebServerEvents.h',
     'FlyWebService.h',
     'HttpServer.h',
 ]
 
 UNIFIED_SOURCES += [
     'FlyWebDiscoveryManager.cpp',
     'FlyWebPublishedServer.cpp',
     'FlyWebServerEvents.cpp',
     'FlyWebService.cpp',
     'HttpServer.cpp'
 ]
 
-#include('/ipc/chromium/chromium-config.mozbuild')
+IPDL_SOURCES += [
+    'PFlyWebPublishedServer.ipdl',
+]
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/dom/base',
     '/netwerk/base',
     '/netwerk/dns',
     '/netwerk/protocol/websocket',
     '/xpcom/io'
 ]
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
 if CONFIG['GNU_CXX']:
     CXXFLAGS += ['-Wshadow']
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -27,16 +27,17 @@
 #include "mozilla/devtools/HeapSnapshotTempFileHelperChild.h"
 #include "mozilla/docshell/OfflineCacheUpdateChild.h"
 #include "mozilla/dom/ContentBridgeChild.h"
 #include "mozilla/dom/ContentBridgeParent.h"
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/DataTransfer.h"
 #include "mozilla/dom/DOMStorageIPC.h"
 #include "mozilla/dom/ExternalHelperAppChild.h"
+#include "mozilla/dom/FlyWebPublishedServerIPC.h"
 #include "mozilla/dom/PCrashReporterChild.h"
 #include "mozilla/dom/ProcessGlobal.h"
 #include "mozilla/dom/Promise.h"
 #include "mozilla/dom/nsIContentChild.h"
 #include "mozilla/psm/PSMContentListener.h"
 #include "mozilla/hal_sandbox/PHalChild.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/FileDescriptorSetChild.h"
@@ -1684,16 +1685,32 @@ ContentChild::AllocPPresentationChild()
 
 bool
 ContentChild::DeallocPPresentationChild(PPresentationChild* aActor)
 {
   delete aActor;
   return true;
 }
 
+PFlyWebPublishedServerChild*
+ContentChild::AllocPFlyWebPublishedServerChild(const nsString& name,
+                                               const FlyWebPublishOptions& params)
+{
+  MOZ_CRASH("We should never be manually allocating PFlyWebPublishedServerChild actors");
+  return nullptr;
+}
+
+bool
+ContentChild::DeallocPFlyWebPublishedServerChild(PFlyWebPublishedServerChild* aActor)
+{
+  RefPtr<FlyWebPublishedServerChild> actor =
+    dont_AddRef(static_cast<FlyWebPublishedServerChild*>(aActor));
+  return true;
+}
+
 bool
 ContentChild::RecvNotifyPresentationReceiverLaunched(PBrowserChild* aIframe,
                                                      const nsString& aSessionId)
 {
   nsCOMPtr<nsIDocShell> docShell =
     do_GetInterface(static_cast<TabChild*>(aIframe)->WebNavigation());
   NS_WARN_IF(!docShell);
 
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -356,16 +356,22 @@ public:
   virtual PFMRadioChild* AllocPFMRadioChild() override;
 
   virtual bool DeallocPFMRadioChild(PFMRadioChild* aActor) override;
 
   virtual PPresentationChild* AllocPPresentationChild() override;
 
   virtual bool DeallocPPresentationChild(PPresentationChild* aActor) override;
 
+  virtual PFlyWebPublishedServerChild*
+    AllocPFlyWebPublishedServerChild(const nsString& name,
+                                     const FlyWebPublishOptions& params) override;
+
+  virtual bool DeallocPFlyWebPublishedServerChild(PFlyWebPublishedServerChild* aActor) override;
+
   virtual bool
   RecvNotifyPresentationReceiverLaunched(PBrowserChild* aIframe,
                                          const nsString& aSessionId) override;
 
   virtual bool
   RecvNotifyPresentationReceiverCleanUp(const nsString& aSessionId) override;
 
   virtual bool RecvNotifyGMPsChanged() override;
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -63,16 +63,17 @@
 #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
 #include "mozilla/dom/icc/IccParent.h"
 #include "mozilla/dom/mobileconnection/MobileConnectionParent.h"
 #include "mozilla/dom/mobilemessage/SmsParent.h"
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/Permissions.h"
 #include "mozilla/dom/PresentationParent.h"
 #include "mozilla/dom/PPresentationParent.h"
+#include "mozilla/dom/FlyWebPublishedServerIPC.h"
 #include "mozilla/dom/quota/QuotaManagerService.h"
 #include "mozilla/dom/telephony/TelephonyParent.h"
 #include "mozilla/dom/time/DateCacheCleaner.h"
 #include "mozilla/dom/voicemail/VoicemailParent.h"
 #include "mozilla/embedding/printingui/PrintingParent.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "mozilla/ipc/BackgroundChild.h"
@@ -4143,16 +4144,33 @@ ContentParent::DeallocPPresentationParen
 }
 
 bool
 ContentParent::RecvPPresentationConstructor(PPresentationParent* aActor)
 {
   return static_cast<PresentationParent*>(aActor)->Init();
 }
 
+PFlyWebPublishedServerParent*
+ContentParent::AllocPFlyWebPublishedServerParent(const nsString& name,
+                                                 const FlyWebPublishOptions& params)
+{
+  RefPtr<FlyWebPublishedServerParent> actor =
+    new FlyWebPublishedServerParent(name, params);
+  return actor.forget().take();
+}
+
+bool
+ContentParent::DeallocPFlyWebPublishedServerParent(PFlyWebPublishedServerParent* aActor)
+{
+  RefPtr<FlyWebPublishedServerParent> actor =
+    dont_AddRef(static_cast<FlyWebPublishedServerParent*>(aActor));
+  return true;
+}
+
 PSpeechSynthesisParent*
 ContentParent::AllocPSpeechSynthesisParent()
 {
 #ifdef MOZ_WEBSPEECH
   return new mozilla::dom::SpeechSynthesisParent();
 #else
   return nullptr;
 #endif
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -863,16 +863,22 @@ private:
   virtual bool DeallocPFMRadioParent(PFMRadioParent* aActor) override;
 
   virtual PPresentationParent* AllocPPresentationParent() override;
 
   virtual bool DeallocPPresentationParent(PPresentationParent* aActor) override;
 
   virtual bool RecvPPresentationConstructor(PPresentationParent* aActor) override;
 
+  virtual PFlyWebPublishedServerParent*
+    AllocPFlyWebPublishedServerParent(const nsString& name,
+                                      const FlyWebPublishOptions& params) override;
+
+  virtual bool DeallocPFlyWebPublishedServerParent(PFlyWebPublishedServerParent* aActor) override;
+
   virtual PSpeechSynthesisParent* AllocPSpeechSynthesisParent() override;
 
   virtual bool
   DeallocPSpeechSynthesisParent(PSpeechSynthesisParent* aActor) override;
 
   virtual bool
   RecvPSpeechSynthesisConstructor(PSpeechSynthesisParent* aActor) override;
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -52,16 +52,17 @@ include protocol PTelephony;
 include protocol PTestShell;
 include protocol PVoicemail;
 include protocol PJavaScript;
 include protocol PRemoteSpellcheckEngine;
 include protocol PWebBrowserPersistDocument;
 include protocol PWebrtcGlobal;
 include protocol PPresentation;
 include protocol PVRManager;
+include protocol PFlyWebPublishedServer;
 include DOMTypes;
 include JavaScriptTypes;
 include InputStreamParams;
 include PTabContext;
 include URIParams;
 include PluginTypes;
 include ProtocolTypes;
 include PBackgroundSharedTypes;
@@ -93,16 +94,17 @@ using mozilla::gfx::IntSize from "mozill
 using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
 using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h";
 using mozilla::LayoutDeviceIntPoint from "Units.h";
 using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h";
 using class mozilla::dom::ipc::StructuredCloneData from "ipc/IPCMessageUtils.h";
 using mozilla::DataStorageType from "ipc/DataStorageIPCUtils.h";
 using mozilla::DocShellOriginAttributes from "mozilla/ipc/BackgroundUtils.h";
 using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
+using struct mozilla::dom::FlyWebPublishOptions from "mozilla/dom/FlyWebPublishOptionsIPCSerializer.h";
 
 union ChromeRegistryItem
 {
     ChromePackage;
     OverrideMapping;
     SubstitutionMapping;
 };
 
@@ -428,16 +430,17 @@ prio(normal upto urgent) sync protocol P
     manages PTelephony;
     manages PTestShell;
     manages PVoicemail;
     manages PJavaScript;
     manages PRemoteSpellcheckEngine;
     manages PWebBrowserPersistDocument;
     manages PWebrtcGlobal;
     manages PPresentation;
+    manages PFlyWebPublishedServer;
 
 both:
     // Depending on exactly how the new browser is being created, it might be
     // created from either the child or parent process!
     //
     // The child creates the PBrowser as part of
     // TabChild::BrowserFrameProvideWindow (which happens when the child's
     // content calls window.open()), and the parent creates the PBrowser as part
@@ -848,16 +851,18 @@ parent:
     async PBluetooth();
 
     async PFMRadio();
 
     async PWebrtcGlobal();
 
     async PPresentation();
 
+    async PFlyWebPublishedServer(nsString name, FlyWebPublishOptions params);
+
     // Services remoting
 
     async StartVisitedQuery(URIParams uri);
     async VisitURI(URIParams uri, OptionalURIParams referrer, uint32_t flags);
     async SetURITitle(URIParams uri, nsString title);
 
     async LoadURIExternal(URIParams uri, PBrowser windowContext);