summaryrefslogtreecommitdiffstats
path: root/dom/flyweb/FlyWebPublishedServer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/flyweb/FlyWebPublishedServer.cpp')
-rw-r--r--dom/flyweb/FlyWebPublishedServer.cpp675
1 files changed, 0 insertions, 675 deletions
diff --git a/dom/flyweb/FlyWebPublishedServer.cpp b/dom/flyweb/FlyWebPublishedServer.cpp
deleted file mode 100644
index 375df332f..000000000
--- a/dom/flyweb/FlyWebPublishedServer.cpp
+++ /dev/null
@@ -1,675 +0,0 @@
-/* -*- 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/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/dom/ContentParent.h"
-#include "mozilla/dom/InternalResponse.h"
-#include "mozilla/ipc/IPCStreamUtils.h"
-#include "mozilla/net/NeckoParent.h"
-#include "mozilla/net/IPCTransportProvider.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/Unused.h"
-#include "nsCharSeparatedTokenizer.h"
-#include "nsGlobalWindow.h"
-#include "WebSocketChannel.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__))
-
-/******** FlyWebPublishedServer ********/
-
-FlyWebPublishedServer::FlyWebPublishedServer(nsPIDOMWindowInner* aOwner,
- const nsAString& aName,
- const FlyWebPublishOptions& aOptions)
- : mozilla::DOMEventTargetHelper(aOwner)
- , mOwnerWindowID(aOwner ? aOwner->WindowID() : 0)
- , mName(aName)
- , mUiUrl(aOptions.mUiUrl)
- , mIsRegistered(true) // Registered by the FlyWebService
-{
-}
-
-void
-FlyWebPublishedServer::LastRelease()
-{
- // 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) {
- 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__);
- }
-}
-
-already_AddRefed<WebSocket>
-FlyWebPublishedServer::OnWebSocketAccept(InternalRequest* aConnectRequest,
- const Optional<nsAString>& aProtocol,
- ErrorResult& aRv)
-{
- MOZ_ASSERT(aConnectRequest);
-
- LOG_I("FlyWebPublishedServer::OnWebSocketAccept(%p)", this);
-
- nsCOMPtr<nsITransportProvider> provider =
- OnWebSocketAcceptInternal(aConnectRequest,
- aProtocol,
- aRv);
- if (aRv.Failed()) {
- return nullptr;
- }
- MOZ_ASSERT(provider);
-
- nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(GetOwner());
- AutoJSContext cx;
- GlobalObject global(cx, nsGlobalWindow::Cast(window)->FastGetGlobalJSObject());
-
- nsAutoCString extensions, negotiatedExtensions;
- aConnectRequest->Headers()->
- GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Extensions"), extensions, aRv);
- mozilla::net::ProcessServerWebSocketExtensions(extensions,
- negotiatedExtensions);
-
- nsCString url;
- aConnectRequest->GetURL(url);
- Sequence<nsString> protocols;
- if (aProtocol.WasPassed() &&
- !protocols.AppendElement(aProtocol.Value(), fallible)) {
- aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
- return nullptr;
- }
-
- return WebSocket::ConstructorCommon(global,
- NS_ConvertUTF8toUTF16(url),
- protocols,
- provider,
- negotiatedExtensions,
- aRv);
-}
-
-/******** 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);
-}
-
-void
-FlyWebPublishedServerImpl::PermissionGranted(bool aGranted)
-{
- LOG_I("FlyWebPublishedServerImpl::PermissionGranted(%b)", aGranted);
- if (!aGranted) {
- PublishedServerStarted(NS_ERROR_FAILURE);
- return;
- }
-
- 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
-FlyWebPublishedServerImpl::OnServerStarted(nsresult aStatus)
-{
- if (NS_SUCCEEDED(aStatus)) {
- FlyWebService::GetOrCreate()->StartDiscoveryOf(this);
- } else {
- PublishedServerStarted(aStatus);
- }
-}
-
-void
-FlyWebPublishedServerImpl::OnFetchResponse(InternalRequest* aRequest,
- InternalResponse* aResponse)
-{
- MOZ_ASSERT(aRequest);
- MOZ_ASSERT(aResponse);
-
- LOG_I("FlyWebPublishedServerImpl::OnFetchResponse(%p)", this);
-
- if (mHttpServer) {
- mHttpServer->SendResponse(aRequest, aResponse);
- }
-}
-
-void
-FlyWebPublishedServerImpl::OnWebSocketResponse(InternalRequest* aConnectRequest,
- InternalResponse* aResponse)
-{
- MOZ_ASSERT(aConnectRequest);
- MOZ_ASSERT(aResponse);
-
- LOG_I("FlyWebPublishedMDNSServer::OnWebSocketResponse(%p)", this);
-
- if (mHttpServer) {
- mHttpServer->SendWebSocketResponse(aConnectRequest, aResponse);
- }
-}
-
-already_AddRefed<nsITransportProvider>
-FlyWebPublishedServerImpl::OnWebSocketAcceptInternal(InternalRequest* aConnectRequest,
- const Optional<nsAString>& aProtocol,
- ErrorResult& aRv)
-{
- LOG_I("FlyWebPublishedServerImpl::OnWebSocketAcceptInternal(%p)", this);
-
- if (!mHttpServer) {
- aRv.Throw(NS_ERROR_UNEXPECTED);
- return nullptr;
- }
-
- return mHttpServer->AcceptWebSocket(aConnectRequest,
- aProtocol,
- aRv);
-}
-
-/******** FlyWebPublishedServerChild ********/
-
-FlyWebPublishedServerChild::FlyWebPublishedServerChild(nsPIDOMWindowInner* aOwner,
- const nsAString& aName,
- const FlyWebPublishOptions& aOptions)
- : FlyWebPublishedServer(aOwner, aName, aOptions)
- , mActorExists(false)
-{
- LOG_I("FlyWebPublishedServerChild::FlyWebPublishedServerChild(%p)", this);
-
- // The matching release happens when the actor is destroyed, in
- // ContentChild::DeallocPFlyWebPublishedServerChild
- NS_ADDREF_THIS();
-}
-
-void
-FlyWebPublishedServerChild::PermissionGranted(bool aGranted)
-{
- if (!aGranted) {
- PublishedServerStarted(NS_ERROR_FAILURE);
- return;
- }
-
- mActorExists = true;
- FlyWebPublishOptions options;
- options.mUiUrl = mUiUrl;
-
- // Proceed with initialization.
- ContentChild::GetSingleton()->
- SendPFlyWebPublishedServerConstructor(this, mName, options);
-}
-
-bool
-FlyWebPublishedServerChild::RecvServerReady(const nsresult& aStatus)
-{
- LOG_I("FlyWebPublishedServerChild::RecvServerReady(%p)", this);
- MOZ_ASSERT(mActorExists);
-
- PublishedServerStarted(aStatus);
- return true;
-}
-
-bool
-FlyWebPublishedServerChild::RecvServerClose()
-{
- LOG_I("FlyWebPublishedServerChild::RecvServerClose(%p)", this);
- MOZ_ASSERT(mActorExists);
-
- Close();
-
- return true;
-}
-
-bool
-FlyWebPublishedServerChild::RecvFetchRequest(const IPCInternalRequest& aRequest,
- const uint64_t& aRequestId)
-{
- LOG_I("FlyWebPublishedServerChild::RecvFetchRequest(%p)", this);
- MOZ_ASSERT(mActorExists);
-
- RefPtr<InternalRequest> request = new InternalRequest(aRequest);
- mPendingRequests.Put(request, aRequestId);
- FireFetchEvent(request);
-
- return true;
-}
-
-bool
-FlyWebPublishedServerChild::RecvWebSocketRequest(const IPCInternalRequest& aRequest,
- const uint64_t& aRequestId,
- PTransportProviderChild* aProvider)
-{
- LOG_I("FlyWebPublishedServerChild::RecvWebSocketRequest(%p)", this);
- MOZ_ASSERT(mActorExists);
-
- RefPtr<InternalRequest> request = new InternalRequest(aRequest);
- mPendingRequests.Put(request, aRequestId);
-
- // Not addreffing here. The addref was already done when the
- // PTransportProvider child constructor original ran.
- mPendingTransportProviders.Put(aRequestId,
- dont_AddRef(static_cast<TransportProviderChild*>(aProvider)));
-
- FireWebsocketEvent(request);
-
- return true;
-}
-
-void
-FlyWebPublishedServerChild::ActorDestroy(ActorDestroyReason aWhy)
-{
- LOG_I("FlyWebPublishedServerChild::ActorDestroy(%p)", this);
-
- mActorExists = false;
-}
-
-void
-FlyWebPublishedServerChild::OnFetchResponse(InternalRequest* aRequest,
- InternalResponse* aResponse)
-{
- LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
-
- if (!mActorExists) {
- LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
- return;
- }
-
- uint64_t id = mPendingRequests.Get(aRequest);
- MOZ_ASSERT(id);
- mPendingRequests.Remove(aRequest);
-
- IPCInternalResponse ipcResp;
- UniquePtr<mozilla::ipc::AutoIPCStream> autoStream;
- nsIContentChild* cc = static_cast<ContentChild*>(Manager());
- aResponse->ToIPC(&ipcResp, cc, autoStream);
- Unused << SendFetchResponse(ipcResp, id);
- if (autoStream) {
- autoStream->TakeOptionalValue();
- }
-}
-
-already_AddRefed<nsITransportProvider>
-FlyWebPublishedServerChild::OnWebSocketAcceptInternal(InternalRequest* aRequest,
- const Optional<nsAString>& aProtocol,
- ErrorResult& aRv)
-{
- LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p)", this);
-
- if (!mActorExists) {
- LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p) - No actor!", this);
- return nullptr;
- }
-
- uint64_t id = mPendingRequests.Get(aRequest);
- MOZ_ASSERT(id);
- mPendingRequests.Remove(aRequest);
-
- RefPtr<TransportProviderChild> provider;
- mPendingTransportProviders.Remove(id, getter_AddRefs(provider));
-
- nsString protocol;
- if (aProtocol.WasPassed()) {
- protocol = aProtocol.Value();
-
- nsAutoCString reqProtocols;
- aRequest->Headers()->
- GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Protocol"), reqProtocols, aRv);
- if (!ContainsToken(reqProtocols, NS_ConvertUTF16toUTF8(protocol))) {
- // Should throw a better error here
- aRv.Throw(NS_ERROR_FAILURE);
- return nullptr;
- }
- } else {
- protocol.SetIsVoid(true);
- }
-
- Unused << SendWebSocketAccept(protocol, id);
-
- return provider.forget();
-}
-
-void
-FlyWebPublishedServerChild::OnWebSocketResponse(InternalRequest* aRequest,
- InternalResponse* aResponse)
-{
- LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
-
- if (!mActorExists) {
- LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
- return;
- }
-
- uint64_t id = mPendingRequests.Get(aRequest);
- MOZ_ASSERT(id);
- mPendingRequests.Remove(aRequest);
-
- mPendingTransportProviders.Remove(id);
-
- IPCInternalResponse ipcResp;
- UniquePtr<mozilla::ipc::AutoIPCStream> autoStream;
- nsIContentChild* cc = static_cast<ContentChild*>(Manager());
- aResponse->ToIPC(&ipcResp, cc, autoStream);
-
- Unused << SendWebSocketResponse(ipcResp, id);
- if (autoStream) {
- autoStream->TakeOptionalValue();
- }
-}
-
-void
-FlyWebPublishedServerChild::Close()
-{
- LOG_I("FlyWebPublishedServerChild::Close(%p)", this);
-
- FlyWebPublishedServer::Close();
-
- if (mActorExists) {
- LOG_I("FlyWebPublishedServerChild::Close - sending __delete__ (%p)", this);
-
- Send__delete__(this);
- }
-}
-
-/******** FlyWebPublishedServerParent ********/
-
-NS_IMPL_ISUPPORTS(FlyWebPublishedServerParent, nsIDOMEventListener)
-
-FlyWebPublishedServerParent::FlyWebPublishedServerParent(const nsAString& aName,
- const FlyWebPublishOptions& aOptions)
- : mActorDestroyed(false)
- , mNextRequestId(1)
-{
- 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) {
- mPublishedServer->Close();
- return;
- }
-
- mPublishedServer->AddEventListener(NS_LITERAL_STRING("fetch"),
- this, false, false, 2);
- mPublishedServer->AddEventListener(NS_LITERAL_STRING("websocket"),
- this, false, false, 2);
- mPublishedServer->AddEventListener(NS_LITERAL_STRING("close"),
- this, false, false, 2);
- Unused << SendServerReady(NS_OK);
- },
- [this, self] (nsresult aStatus) {
- MOZ_ASSERT(NS_FAILED(aStatus));
- if (!mActorDestroyed) {
- Unused << SendServerReady(aStatus);
- }
- });
-}
-
-NS_IMETHODIMP
-FlyWebPublishedServerParent::HandleEvent(nsIDOMEvent* aEvent)
-{
- if (mActorDestroyed) {
- return NS_OK;
- }
-
- nsAutoString type;
- aEvent->GetType(type);
- if (type.EqualsLiteral("close")) {
- Unused << SendServerClose();
- return NS_OK;
- }
-
- if (type.EqualsLiteral("fetch")) {
- RefPtr<InternalRequest> request =
- static_cast<FlyWebFetchEvent*>(aEvent)->Request()->GetInternalRequest();
- uint64_t id = mNextRequestId++;
- mPendingRequests.Put(id, request);
-
- IPCInternalRequest ipcReq;
- request->ToIPC(&ipcReq);
- Unused << SendFetchRequest(ipcReq, id);
- return NS_OK;
- }
-
- if (type.EqualsLiteral("websocket")) {
- RefPtr<InternalRequest> request =
- static_cast<FlyWebWebSocketEvent*>(aEvent)->Request()->GetInternalRequest();
- uint64_t id = mNextRequestId++;
- mPendingRequests.Put(id, request);
-
- nsTArray<PNeckoParent*> neckoParents;
- Manager()->ManagedPNeckoParent(neckoParents);
- if (neckoParents.Length() != 1) {
- MOZ_CRASH("Expected exactly 1 PNeckoParent instance per PNeckoChild");
- }
-
- RefPtr<TransportProviderParent> provider =
- static_cast<TransportProviderParent*>(
- neckoParents[0]->SendPTransportProviderConstructor());
-
- IPCInternalRequest ipcReq;
- request->ToIPC(&ipcReq);
- Unused << SendWebSocketRequest(ipcReq, id, provider);
-
- mPendingTransportProviders.Put(id, provider.forget());
- return NS_OK;
- }
-
- MOZ_CRASH("Unknown event type");
-
- return NS_OK;
-}
-
-bool
-FlyWebPublishedServerParent::RecvFetchResponse(const IPCInternalResponse& aResponse,
- const uint64_t& aRequestId)
-{
- MOZ_ASSERT(!mActorDestroyed);
-
- RefPtr<InternalRequest> request;
- mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
- if (!request) {
- static_cast<ContentParent*>(Manager())->KillHard("unknown request id");
- return false;
- }
-
- RefPtr<InternalResponse> response = InternalResponse::FromIPC(aResponse);
-
- mPublishedServer->OnFetchResponse(request, response);
-
- return true;
-}
-
-bool
-FlyWebPublishedServerParent::RecvWebSocketResponse(const IPCInternalResponse& aResponse,
- const uint64_t& aRequestId)
-{
- MOZ_ASSERT(!mActorDestroyed);
-
- mPendingTransportProviders.Remove(aRequestId);
-
- RefPtr<InternalRequest> request;
- mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
- if (!request) {
- static_cast<ContentParent*>(Manager())->KillHard("unknown websocket request id");
- return false;
- }
-
- RefPtr<InternalResponse> response = InternalResponse::FromIPC(aResponse);
-
- mPublishedServer->OnWebSocketResponse(request, response);
-
- return true;
-}
-
-bool
-FlyWebPublishedServerParent::RecvWebSocketAccept(const nsString& aProtocol,
- const uint64_t& aRequestId)
-{
- MOZ_ASSERT(!mActorDestroyed);
-
- RefPtr<TransportProviderParent> providerIPC;
- mPendingTransportProviders.Remove(aRequestId, getter_AddRefs(providerIPC));
-
- RefPtr<InternalRequest> request;
- mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
-
- if (!request || !providerIPC) {
- static_cast<ContentParent*>(Manager())->KillHard("unknown websocket request id");
- return false;
- }
-
- Optional<nsAString> protocol;
- if (!aProtocol.IsVoid()) {
- protocol = &aProtocol;
- }
-
- ErrorResult result;
- nsCOMPtr<nsITransportProvider> providerServer =
- mPublishedServer->OnWebSocketAcceptInternal(request, protocol, result);
- if (result.Failed()) {
- return false;
- }
-
- providerServer->SetListener(providerIPC);
-
- return true;
-}
-
-void
-FlyWebPublishedServerParent::ActorDestroy(ActorDestroyReason aWhy)
-{
- LOG_I("FlyWebPublishedServerParent::ActorDestroy(%p)", this);
-
- mActorDestroyed = true;
-}
-
-bool
-FlyWebPublishedServerParent::Recv__delete__()
-{
- LOG_I("FlyWebPublishedServerParent::Recv__delete__(%p)", this);
- MOZ_ASSERT(!mActorDestroyed);
-
- if (mPublishedServer) {
- mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("fetch"),
- this, false);
- mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("websocket"),
- this, false);
- mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("close"),
- this, false);
- mPublishedServer->Close();
- mPublishedServer = nullptr;
- }
- return true;
-}
-
-} // namespace dom
-} // namespace mozilla
-
-