diff options
Diffstat (limited to 'dom/flyweb/FlyWebPublishedServer.cpp')
-rw-r--r-- | dom/flyweb/FlyWebPublishedServer.cpp | 675 |
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 - - |