summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dom/flyweb/FlyWebDiscoveryManager.cpp125
-rw-r--r--dom/flyweb/FlyWebDiscoveryManager.h61
-rw-r--r--dom/flyweb/FlyWebPublishOptionsIPCSerializer.h33
-rw-r--r--dom/flyweb/FlyWebPublishedServer.cpp675
-rw-r--r--dom/flyweb/FlyWebPublishedServer.h109
-rw-r--r--dom/flyweb/FlyWebPublishedServerIPC.h172
-rw-r--r--dom/flyweb/FlyWebServerEvents.cpp141
-rw-r--r--dom/flyweb/FlyWebServerEvents.h88
-rw-r--r--dom/flyweb/FlyWebService.cpp1310
-rw-r--r--dom/flyweb/FlyWebService.h113
-rw-r--r--dom/flyweb/HttpServer.cpp1319
-rw-r--r--dom/flyweb/HttpServer.h193
-rw-r--r--dom/flyweb/PFlyWebPublishedServer.ipdl38
-rw-r--r--dom/flyweb/moz.build42
14 files changed, 0 insertions, 4419 deletions
diff --git a/dom/flyweb/FlyWebDiscoveryManager.cpp b/dom/flyweb/FlyWebDiscoveryManager.cpp
deleted file mode 100644
index 5a97eb6d8..000000000
--- a/dom/flyweb/FlyWebDiscoveryManager.cpp
+++ /dev/null
@@ -1,125 +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 "nsString.h"
-#include "nsTHashtable.h"
-#include "nsClassHashtable.h"
-#include "nsIUUIDGenerator.h"
-#include "jsapi.h"
-#include "mozilla/StaticPtr.h"
-#include "mozilla/Logging.h"
-#include "nsComponentManagerUtils.h"
-#include "nsServiceManagerUtils.h"
-
-#include "mozilla/dom/FlyWebDiscoveryManager.h"
-#include "mozilla/dom/FlyWebDiscoveryManagerBinding.h"
-
-namespace mozilla {
-namespace dom {
-
-static LazyLogModule gFlyWebDiscoveryManagerLog("FlyWebDiscoveryManager");
-#undef LOG_I
-#define LOG_I(...) MOZ_LOG(mozilla::dom::gFlyWebDiscoveryManagerLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-#undef LOG_E
-#define LOG_E(...) MOZ_LOG(mozilla::dom::gFlyWebDiscoveryManagerLog, mozilla::LogLevel::Error, (__VA_ARGS__))
-
-
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(FlyWebDiscoveryManager)
-
-NS_IMPL_CYCLE_COLLECTING_ADDREF(FlyWebDiscoveryManager)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(FlyWebDiscoveryManager)
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FlyWebDiscoveryManager)
- NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
-
-FlyWebDiscoveryManager::FlyWebDiscoveryManager(nsISupports* aParent,
- FlyWebService* aService)
- : mParent(aParent)
- , mService(aService)
- , mNextId(0)
-{
-}
-
-FlyWebDiscoveryManager::~FlyWebDiscoveryManager()
-{
- mService->UnregisterDiscoveryManager(this);
-}
-
-JSObject*
-FlyWebDiscoveryManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return FlyWebDiscoveryManagerBinding::Wrap(aCx, this, aGivenProto);
-}
-
-nsISupports*
-FlyWebDiscoveryManager::GetParentObject() const
-{
- return mParent;
-}
-
-/* static */ already_AddRefed<FlyWebDiscoveryManager>
-FlyWebDiscoveryManager::Constructor(const GlobalObject& aGlobal, ErrorResult& rv)
-{
- RefPtr<FlyWebService> service = FlyWebService::GetOrCreate();
- if (!service) {
- return nullptr;
- }
-
- RefPtr<FlyWebDiscoveryManager> result = new FlyWebDiscoveryManager(
- aGlobal.GetAsSupports(), service);
- return result.forget();
-}
-
-void
-FlyWebDiscoveryManager::ListServices(nsTArray<FlyWebDiscoveredService>& aServices)
-{
- return mService->ListDiscoveredServices(aServices);
-}
-
-uint32_t
-FlyWebDiscoveryManager::StartDiscovery(FlyWebDiscoveryCallback& aCallback)
-{
- uint32_t id = GenerateId();
- mCallbackMap.Put(id, &aCallback);
- mService->RegisterDiscoveryManager(this);
- return id;
-}
-
-void
-FlyWebDiscoveryManager::StopDiscovery(uint32_t aId)
-{
- mCallbackMap.Remove(aId);
- if (mCallbackMap.Count() == 0) {
- mService->UnregisterDiscoveryManager(this);
- }
-}
-
-void
-FlyWebDiscoveryManager::PairWithService(const nsAString& aServiceId,
- FlyWebPairingCallback& aCallback)
-{
- mService->PairWithService(aServiceId, aCallback);
-}
-
-void
-FlyWebDiscoveryManager::NotifyDiscoveredServicesChanged()
-{
- nsTArray<FlyWebDiscoveredService> services;
- ListServices(services);
- Sequence<FlyWebDiscoveredService> servicesSeq;
- servicesSeq.SwapElements(services);
- for (auto iter = mCallbackMap.Iter(); !iter.Done(); iter.Next()) {
- FlyWebDiscoveryCallback *callback = iter.UserData();
- ErrorResult err;
- callback->OnDiscoveredServicesChanged(servicesSeq, err);
- ENSURE_SUCCESS_VOID(err);
- }
-}
-
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/flyweb/FlyWebDiscoveryManager.h b/dom/flyweb/FlyWebDiscoveryManager.h
deleted file mode 100644
index cb5f692f8..000000000
--- a/dom/flyweb/FlyWebDiscoveryManager.h
+++ /dev/null
@@ -1,61 +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/. */
-
-#ifndef mozilla_dom_FlyWebDiscoveryManager_h
-#define mozilla_dom_FlyWebDiscoveryManager_h
-
-#include "nsISupportsImpl.h"
-#include "mozilla/ErrorResult.h"
-#include "nsRefPtrHashtable.h"
-#include "nsWrapperCache.h"
-#include "FlyWebDiscoveryManagerBinding.h"
-#include "FlyWebService.h"
-
-namespace mozilla {
-namespace dom {
-
-class FlyWebDiscoveryManager final : public nsISupports
- , public nsWrapperCache
-{
-public:
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(FlyWebDiscoveryManager)
-
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
- nsISupports* GetParentObject() const;
-
- static already_AddRefed<FlyWebDiscoveryManager> Constructor(const GlobalObject& aGlobal,
- ErrorResult& rv);
-
- void ListServices(nsTArray<FlyWebDiscoveredService>& aServices);
- uint32_t StartDiscovery(FlyWebDiscoveryCallback& aCallback);
- void StopDiscovery(uint32_t aId);
-
- void PairWithService(const nsAString& aServiceId,
- FlyWebPairingCallback& callback);
-
- void NotifyDiscoveredServicesChanged();
-
-private:
- FlyWebDiscoveryManager(nsISupports* mParent, FlyWebService* aService);
- ~FlyWebDiscoveryManager();
-
- uint32_t GenerateId() {
- return ++mNextId;
- }
-
- nsCOMPtr<nsISupports> mParent;
- RefPtr<FlyWebService> mService;
-
- uint32_t mNextId;
-
- nsRefPtrHashtable<nsUint32HashKey, FlyWebDiscoveryCallback> mCallbackMap;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_FlyWebDiscoveryManager_h
diff --git a/dom/flyweb/FlyWebPublishOptionsIPCSerializer.h b/dom/flyweb/FlyWebPublishOptionsIPCSerializer.h
deleted file mode 100644
index fa1a44113..000000000
--- a/dom/flyweb/FlyWebPublishOptionsIPCSerializer.h
+++ /dev/null
@@ -1,33 +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/. */
-
-#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
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
-
-
diff --git a/dom/flyweb/FlyWebPublishedServer.h b/dom/flyweb/FlyWebPublishedServer.h
deleted file mode 100644
index ec3a685ec..000000000
--- a/dom/flyweb/FlyWebPublishedServer.h
+++ /dev/null
@@ -1,109 +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/. */
-
-#ifndef mozilla_dom_FlyWebPublishedServer_h
-#define mozilla_dom_FlyWebPublishedServer_h
-
-#include "mozilla/DOMEventTargetHelper.h"
-#include "mozilla/MozPromise.h"
-
-class nsPIDOMWindowInner;
-class nsITransportProvider;
-
-namespace mozilla {
-
-class ErrorResult;
-
-namespace dom {
-
-class InternalResponse;
-class InternalRequest;
-class WebSocket;
-struct FlyWebPublishOptions;
-class FlyWebPublishedServer;
-
-typedef MozPromise<RefPtr<FlyWebPublishedServer>, nsresult, false>
- FlyWebPublishPromise;
-
-class FlyWebPublishedServer : public mozilla::DOMEventTargetHelper
-{
-public:
- FlyWebPublishedServer(nsPIDOMWindowInner* aOwner,
- const nsAString& aName,
- const FlyWebPublishOptions& aOptions);
-
- virtual void LastRelease() override;
-
- virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
-
- uint64_t OwnerWindowID() const {
- return mOwnerWindowID;
- }
-
- void GetName(nsAString& aName)
- {
- aName = mName;
- }
- nsAString& Name()
- {
- return mName;
- }
-
- void GetUiUrl(nsAString& aUiUrl)
- {
- aUiUrl = mUiUrl;
- }
-
- virtual void PermissionGranted(bool aGranted) = 0;
-
- virtual void OnFetchResponse(InternalRequest* aRequest,
- InternalResponse* aResponse) = 0;
- already_AddRefed<WebSocket>
- OnWebSocketAccept(InternalRequest* aConnectRequest,
- const Optional<nsAString>& aProtocol,
- ErrorResult& aRv);
- virtual void OnWebSocketResponse(InternalRequest* aConnectRequest,
- InternalResponse* aResponse) = 0;
- virtual already_AddRefed<nsITransportProvider>
- OnWebSocketAcceptInternal(InternalRequest* aConnectRequest,
- const Optional<nsAString>& aProtocol,
- ErrorResult& aRv) = 0;
-
- virtual void Close();
-
- void FireFetchEvent(InternalRequest* aRequest);
- void FireWebsocketEvent(InternalRequest* aConnectRequest);
- void PublishedServerStarted(nsresult aStatus);
-
- IMPL_EVENT_HANDLER(fetch)
- IMPL_EVENT_HANDLER(websocket)
- IMPL_EVENT_HANDLER(close)
-
- already_AddRefed<FlyWebPublishPromise>
- GetPublishPromise()
- {
- return mPublishPromise.Ensure(__func__);
- }
-
-protected:
- virtual ~FlyWebPublishedServer()
- {
- MOZ_ASSERT(!mIsRegistered, "Subclass dtor forgot to call Close()");
- }
-
- uint64_t mOwnerWindowID;
- MozPromiseHolder<FlyWebPublishPromise> mPublishPromise;
-
- nsString mName;
- nsString mUiUrl;
-
- bool mIsRegistered;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_FlyWebPublishedServer_h
diff --git a/dom/flyweb/FlyWebPublishedServerIPC.h b/dom/flyweb/FlyWebPublishedServerIPC.h
deleted file mode 100644
index 942c7847e..000000000
--- a/dom/flyweb/FlyWebPublishedServerIPC.h
+++ /dev/null
@@ -1,172 +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/. */
-
-#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 "nsICancelable.h"
-#include "nsIDOMEventListener.h"
-#include "nsISupportsImpl.h"
-
-class nsPIDOMWindowInner;
-
-namespace mozilla {
-namespace net {
-class TransportProviderParent;
-class TransportProviderChild;
-}
-
-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 PermissionGranted(bool aGranted) override;
- virtual void OnFetchResponse(InternalRequest* aRequest,
- InternalResponse* aResponse) override;
- virtual void OnWebSocketResponse(InternalRequest* aConnectRequest,
- InternalResponse* aResponse) override;
- virtual already_AddRefed<nsITransportProvider>
- OnWebSocketAcceptInternal(InternalRequest* aConnectRequest,
- const Optional<nsAString>& aProtocol,
- ErrorResult& aRv) 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 void PermissionGranted(bool aGranted) override;
- virtual bool RecvServerReady(const nsresult& aStatus) override;
- virtual bool RecvServerClose() override;
- virtual bool RecvFetchRequest(const IPCInternalRequest& aRequest,
- const uint64_t& aRequestId) override;
- virtual bool RecvWebSocketRequest(const IPCInternalRequest& aRequest,
- const uint64_t& aRequestId,
- PTransportProviderChild* aProvider) override;
-
- virtual void OnFetchResponse(InternalRequest* aRequest,
- InternalResponse* aResponse) override;
- virtual void OnWebSocketResponse(InternalRequest* aConnectRequest,
- InternalResponse* aResponse) override;
- virtual already_AddRefed<nsITransportProvider>
- OnWebSocketAcceptInternal(InternalRequest* aConnectRequest,
- const Optional<nsAString>& aProtocol,
- ErrorResult& aRv) override;
-
- virtual void Close() override;
-
- virtual void ActorDestroy(ActorDestroyReason aWhy) override;
-
-private:
- ~FlyWebPublishedServerChild() {}
-
- nsDataHashtable<nsRefPtrHashKey<InternalRequest>, uint64_t> mPendingRequests;
- nsRefPtrHashtable<nsUint64HashKey, TransportProviderChild>
- mPendingTransportProviders;
- bool mActorExists;
-};
-
-class FlyWebPublishedServerParent final : public PFlyWebPublishedServerParent
- , public nsIDOMEventListener
-{
-public:
- FlyWebPublishedServerParent(const nsAString& aName,
- const FlyWebPublishOptions& aOptions);
-
- NS_DECL_ISUPPORTS
- NS_DECL_NSIDOMEVENTLISTENER
-
-private:
- virtual void
- ActorDestroy(ActorDestroyReason aWhy) override;
-
- virtual bool
- Recv__delete__() override;
- virtual bool
- RecvFetchResponse(const IPCInternalResponse& aResponse,
- const uint64_t& aRequestId) override;
- virtual bool
- RecvWebSocketResponse(const IPCInternalResponse& aResponse,
- const uint64_t& aRequestId) override;
- virtual bool
- RecvWebSocketAccept(const nsString& aProtocol,
- const uint64_t& aRequestId) override;
-
- ~FlyWebPublishedServerParent() {}
-
- bool mActorDestroyed;
- uint64_t mNextRequestId;
- nsRefPtrHashtable<nsUint64HashKey, InternalRequest> mPendingRequests;
- nsRefPtrHashtable<nsUint64HashKey, TransportProviderParent>
- mPendingTransportProviders;
- RefPtr<FlyWebPublishedServerImpl> mPublishedServer;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_FlyWebPublishedServerIPC_h
diff --git a/dom/flyweb/FlyWebServerEvents.cpp b/dom/flyweb/FlyWebServerEvents.cpp
deleted file mode 100644
index fe774ffb0..000000000
--- a/dom/flyweb/FlyWebServerEvents.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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/EventBinding.h"
-#include "mozilla/dom/FlyWebFetchEventBinding.h"
-#include "mozilla/dom/FlyWebPublishedServer.h"
-#include "mozilla/dom/FlyWebServerEvents.h"
-#include "mozilla/dom/FlyWebWebSocketEventBinding.h"
-#include "mozilla/dom/Nullable.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/Response.h"
-
-#include "js/GCAPI.h"
-
-namespace mozilla {
-namespace dom {
-
-
-NS_IMPL_CYCLE_COLLECTION_CLASS(FlyWebFetchEvent)
-
-NS_IMPL_ADDREF_INHERITED(FlyWebFetchEvent, Event)
-NS_IMPL_RELEASE_INHERITED(FlyWebFetchEvent, Event)
-
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FlyWebFetchEvent, Event)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRequest)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-
-NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(FlyWebFetchEvent, Event)
-NS_IMPL_CYCLE_COLLECTION_TRACE_END
-
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FlyWebFetchEvent, Event)
- NS_IMPL_CYCLE_COLLECTION_UNLINK(mRequest)
-NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FlyWebFetchEvent)
-NS_INTERFACE_MAP_END_INHERITING(Event)
-
-FlyWebFetchEvent::FlyWebFetchEvent(FlyWebPublishedServer* aServer,
- class Request* aRequest,
- InternalRequest* aInternalRequest)
- : Event(aServer, nullptr, nullptr)
- , mRequest(aRequest)
- , mInternalRequest(aInternalRequest)
- , mServer(aServer)
- , mResponded(false)
-{
- MOZ_ASSERT(aServer);
- MOZ_ASSERT(aRequest);
- MOZ_ASSERT(aInternalRequest);
-}
-
-FlyWebFetchEvent::~FlyWebFetchEvent()
-{
-}
-
-JSObject*
-FlyWebFetchEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return FlyWebFetchEventBinding::Wrap(aCx, this, aGivenProto);
-}
-
-void
-FlyWebFetchEvent::RespondWith(Promise& aArg, ErrorResult& aRv)
-{
- if (mResponded) {
- aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
- return;
- }
-
- mResponded = true;
-
- aArg.AppendNativeHandler(this);
-}
-
-void
-FlyWebFetchEvent::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
-{
- RefPtr<Response> response;
- if (aValue.isObject()) {
- UNWRAP_OBJECT(Response, &aValue.toObject(), response);
- }
-
- RefPtr<InternalResponse> intResponse;
- if (response && response->Type() != ResponseType::Opaque) {
- intResponse = response->GetInternalResponse();
- }
-
- if (!intResponse) {
- intResponse = InternalResponse::NetworkError();
- }
-
- NotifyServer(intResponse);
-}
-
-void
-FlyWebFetchEvent::NotifyServer(InternalResponse* aResponse)
-{
- mServer->OnFetchResponse(mInternalRequest, aResponse);
-}
-
-void
-FlyWebFetchEvent::RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue)
-{
- RefPtr<InternalResponse> err = InternalResponse::NetworkError();
-
- NotifyServer(err);
-}
-
-JSObject*
-FlyWebWebSocketEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
-{
- return FlyWebWebSocketEventBinding::Wrap(aCx, this, aGivenProto);
-}
-
-already_AddRefed<WebSocket>
-FlyWebWebSocketEvent::Accept(const Optional<nsAString>& aProtocol,
- ErrorResult& aRv)
-{
- if (mResponded) {
- aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
- return nullptr;
- }
-
- mResponded = true;
-
- return mServer->OnWebSocketAccept(mInternalRequest, aProtocol, aRv);
-}
-
-
-void
-FlyWebWebSocketEvent::NotifyServer(InternalResponse* aResponse)
-{
- mServer->OnWebSocketResponse(mInternalRequest, aResponse);
-}
-
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/flyweb/FlyWebServerEvents.h b/dom/flyweb/FlyWebServerEvents.h
deleted file mode 100644
index f00e86018..000000000
--- a/dom/flyweb/FlyWebServerEvents.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et cindent: */
-/* 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_FlyWebFetchEvent_h
-#define mozilla_dom_FlyWebFetchEvent_h
-
-#include "mozilla/Attributes.h"
-#include "mozilla/ErrorResult.h"
-#include "mozilla/dom/BindingUtils.h"
-#include "mozilla/dom/Event.h"
-#include "mozilla/dom/FlyWebFetchEventBinding.h"
-#include "mozilla/dom/PromiseNativeHandler.h"
-#include "mozilla/dom/WebSocket.h"
-
-struct JSContext;
-namespace mozilla {
-namespace dom {
-
-class Request;
-class Response;
-class FlyWebPublishedServer;
-class InternalRequest;
-class InternalResponse;
-
-class FlyWebFetchEvent : public Event
- , public PromiseNativeHandler
-{
-public:
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(FlyWebFetchEvent, Event)
-
- virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- virtual void
- ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
- virtual void
- RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
-
- class Request* Request() const
- {
- return mRequest;
- }
-
- void RespondWith(Promise& aArg, ErrorResult& aRv);
-
- FlyWebFetchEvent(FlyWebPublishedServer* aServer,
- class Request* aRequest,
- InternalRequest* aInternalRequest);
-
-protected:
- virtual ~FlyWebFetchEvent();
-
- virtual void NotifyServer(InternalResponse* aResponse);
-
- RefPtr<class Request> mRequest;
- RefPtr<InternalRequest> mInternalRequest;
- RefPtr<FlyWebPublishedServer> mServer;
-
- bool mResponded;
-};
-
-class FlyWebWebSocketEvent final : public FlyWebFetchEvent
-{
-public:
- FlyWebWebSocketEvent(FlyWebPublishedServer* aServer,
- class Request* aRequest,
- InternalRequest* aInternalRequest)
- : FlyWebFetchEvent(aServer, aRequest, aInternalRequest)
- {}
-
- virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
-
- already_AddRefed<WebSocket> Accept(const Optional<nsAString>& aProtocol,
- ErrorResult& aRv);
-
-private:
- ~FlyWebWebSocketEvent() {};
-
- virtual void NotifyServer(InternalResponse* aResponse) override;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_FlyWebFetchEvent_h
diff --git a/dom/flyweb/FlyWebService.cpp b/dom/flyweb/FlyWebService.cpp
deleted file mode 100644
index 5f3b0d66f..000000000
--- a/dom/flyweb/FlyWebService.cpp
+++ /dev/null
@@ -1,1310 +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/FlyWebService.h"
-#include "mozilla/ClearOnShutdown.h"
-#include "mozilla/StaticPtr.h"
-#include "mozilla/ScopeExit.h"
-#include "mozilla/dom/Promise.h"
-#include "mozilla/dom/FlyWebPublishedServerIPC.h"
-#include "mozilla/AddonPathService.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"
-#include "DNS.h"
-#include "nsContentPermissionHelper.h"
-#include "nsSocketTransportService2.h"
-#include "nsSocketTransport2.h"
-#include "nsHashPropertyBag.h"
-#include "nsNetUtil.h"
-#include "nsISimpleEnumerator.h"
-#include "nsIProperty.h"
-#include "nsICertOverrideService.h"
-
-namespace mozilla {
-namespace dom {
-
-struct FlyWebPublishOptions;
-
-static LazyLogModule gFlyWebServiceLog("FlyWebService");
-#undef LOG_I
-#define LOG_I(...) MOZ_LOG(mozilla::dom::gFlyWebServiceLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-
-#undef LOG_E
-#define LOG_E(...) MOZ_LOG(mozilla::dom::gFlyWebServiceLog, mozilla::LogLevel::Error, (__VA_ARGS__))
-
-#undef LOG_TEST_I
-#define LOG_TEST_I(...) MOZ_LOG_TEST(mozilla::dom::gFlyWebServiceLog, mozilla::LogLevel::Debug)
-
-class FlyWebPublishServerPermissionCheck final
- : public nsIContentPermissionRequest
- , public nsIRunnable
-{
-public:
- NS_DECL_ISUPPORTS
-
- FlyWebPublishServerPermissionCheck(const nsCString& aServiceName, uint64_t aWindowID,
- FlyWebPublishedServer* aServer)
- : mServiceName(aServiceName)
- , mWindowID(aWindowID)
- , mServer(aServer)
- {}
-
- uint64_t WindowID() const
- {
- return mWindowID;
- }
-
- NS_IMETHOD Run() override
- {
- MOZ_ASSERT(NS_IsMainThread());
-
- nsGlobalWindow* globalWindow = nsGlobalWindow::GetInnerWindowWithId(mWindowID);
- if (!globalWindow) {
- return Cancel();
- }
- mWindow = globalWindow->AsInner();
- if (NS_WARN_IF(!mWindow)) {
- return Cancel();
- }
-
- nsCOMPtr<nsIDocument> doc = mWindow->GetDoc();
- if (NS_WARN_IF(!doc)) {
- return Cancel();
- }
-
- mPrincipal = doc->NodePrincipal();
- MOZ_ASSERT(mPrincipal);
-
- mRequester = new nsContentPermissionRequester(mWindow);
- return nsContentPermissionUtils::AskPermission(this, mWindow);
- }
-
- NS_IMETHOD Cancel() override
- {
- Resolve(false);
- return NS_OK;
- }
-
- NS_IMETHOD Allow(JS::HandleValue aChoices) override
- {
- MOZ_ASSERT(aChoices.isUndefined());
- Resolve(true);
- return NS_OK;
- }
-
- NS_IMETHOD GetTypes(nsIArray** aTypes) override
- {
- nsTArray<nsString> emptyOptions;
- return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("flyweb-publish-server"),
- NS_LITERAL_CSTRING("unused"), emptyOptions, aTypes);
- }
-
- NS_IMETHOD GetRequester(nsIContentPermissionRequester** aRequester) override
- {
- NS_ENSURE_ARG_POINTER(aRequester);
- nsCOMPtr<nsIContentPermissionRequester> requester = mRequester;
- requester.forget(aRequester);
- return NS_OK;
- }
-
- NS_IMETHOD GetPrincipal(nsIPrincipal** aRequestingPrincipal) override
- {
- NS_IF_ADDREF(*aRequestingPrincipal = mPrincipal);
- return NS_OK;
- }
-
- NS_IMETHOD GetWindow(mozIDOMWindow** aRequestingWindow) override
- {
- NS_IF_ADDREF(*aRequestingWindow = mWindow);
- return NS_OK;
- }
-
- NS_IMETHOD GetElement(nsIDOMElement** aRequestingElement) override
- {
- *aRequestingElement = nullptr;
- return NS_OK;
- }
-
-private:
- void Resolve(bool aResolve)
- {
- mServer->PermissionGranted(aResolve);
- }
-
- virtual ~FlyWebPublishServerPermissionCheck() = default;
-
- nsCString mServiceName;
- uint64_t mWindowID;
- RefPtr<FlyWebPublishedServer> mServer;
- nsCOMPtr<nsPIDOMWindowInner> mWindow;
- nsCOMPtr<nsIPrincipal> mPrincipal;
- nsCOMPtr<nsIContentPermissionRequester> mRequester;
-};
-
-NS_IMPL_ISUPPORTS(FlyWebPublishServerPermissionCheck,
- nsIContentPermissionRequest,
- nsIRunnable)
-
-class FlyWebMDNSService final
- : public nsIDNSServiceDiscoveryListener
- , public nsIDNSServiceResolveListener
- , public nsIDNSRegistrationListener
- , public nsITimerCallback
-{
- friend class FlyWebService;
-
-private:
- enum DiscoveryState {
- DISCOVERY_IDLE,
- DISCOVERY_STARTING,
- DISCOVERY_RUNNING,
- DISCOVERY_STOPPING
- };
-
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIDNSSERVICEDISCOVERYLISTENER
- NS_DECL_NSIDNSSERVICERESOLVELISTENER
- NS_DECL_NSIDNSREGISTRATIONLISTENER
- NS_DECL_NSITIMERCALLBACK
-
- explicit FlyWebMDNSService(FlyWebService* aService,
- const nsACString& aServiceType);
-
-private:
- virtual ~FlyWebMDNSService() = default;
-
- nsresult Init();
- 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(FlyWebPublishedServerImpl* aServer);
-
- void EnsureDiscoveryStarted();
- void EnsureDiscoveryStopped();
-
- // Cycle-breaking link to manager.
- FlyWebService* mService;
- nsCString mServiceType;
-
- // Indicates the desired state of the system. If mDiscoveryActive is true,
- // it indicates that backend discovery "should be happening", and discovery
- // events should be forwarded to listeners.
- // If false, the backend discovery "should be idle", and any discovery events
- // that show up should not be forwarded to listeners.
- bool mDiscoveryActive;
-
- uint32_t mNumConsecutiveStartDiscoveryFailures;
-
- // Represents the internal discovery state as it relates to nsDNSServiceDiscovery.
- // When mDiscoveryActive is true, this state will periodically loop from
- // (IDLE => STARTING => RUNNING => STOPPING => IDLE).
- DiscoveryState mDiscoveryState;
-
- nsCOMPtr<nsITimer> mDiscoveryStartTimer;
- nsCOMPtr<nsITimer> mDiscoveryStopTimer;
- nsCOMPtr<nsIDNSServiceDiscovery> mDNSServiceDiscovery;
- nsCOMPtr<nsICancelable> mCancelDiscovery;
- nsTHashtable<nsStringHashKey> mNewServiceSet;
-
- struct DiscoveredInfo
- {
- explicit DiscoveredInfo(nsIDNSServiceInfo* aDNSServiceInfo);
- FlyWebDiscoveredService mService;
- nsCOMPtr<nsIDNSServiceInfo> mDNSServiceInfo;
- };
- nsClassHashtable<nsStringHashKey, DiscoveredInfo> mServiceMap;
-};
-
-void
-LogDNSInfo(nsIDNSServiceInfo* aServiceInfo, const char* aFunc)
-{
- if (!LOG_TEST_I()) {
- return;
- }
-
- nsCString tmp;
- aServiceInfo->GetServiceName(tmp);
- LOG_I("%s: serviceName=%s", aFunc, tmp.get());
-
- aServiceInfo->GetHost(tmp);
- LOG_I("%s: host=%s", aFunc, tmp.get());
-
- aServiceInfo->GetAddress(tmp);
- LOG_I("%s: address=%s", aFunc, tmp.get());
-
- uint16_t port = -2;
- aServiceInfo->GetPort(&port);
- LOG_I("%s: port=%d", aFunc, (int)port);
-
- nsCOMPtr<nsIPropertyBag2> attributes;
- aServiceInfo->GetAttributes(getter_AddRefs(attributes));
- if (!attributes) {
- LOG_I("%s: no attributes", aFunc);
- } else {
- nsCOMPtr<nsISimpleEnumerator> enumerator;
- attributes->GetEnumerator(getter_AddRefs(enumerator));
- MOZ_ASSERT(enumerator);
-
- LOG_I("%s: attributes start", aFunc);
-
- bool hasMoreElements;
- while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements)) &&
- hasMoreElements) {
- nsCOMPtr<nsISupports> element;
- MOZ_ALWAYS_SUCCEEDS(enumerator->GetNext(getter_AddRefs(element)));
- nsCOMPtr<nsIProperty> property = do_QueryInterface(element);
- MOZ_ASSERT(property);
-
- nsAutoString name;
- nsCOMPtr<nsIVariant> value;
- MOZ_ALWAYS_SUCCEEDS(property->GetName(name));
- MOZ_ALWAYS_SUCCEEDS(property->GetValue(getter_AddRefs(value)));
-
- nsAutoCString str;
- nsresult rv = value->GetAsACString(str);
- if (NS_SUCCEEDED(rv)) {
- LOG_I("%s: attribute name=%s value=%s", aFunc,
- NS_ConvertUTF16toUTF8(name).get(), str.get());
- } else {
- uint16_t type;
- MOZ_ALWAYS_SUCCEEDS(value->GetDataType(&type));
- LOG_I("%s: attribute *unstringifiable* name=%s type=%d", aFunc,
- NS_ConvertUTF16toUTF8(name).get(), (int)type);
- }
- }
-
- LOG_I("%s: attributes end", aFunc);
- }
-}
-
-NS_IMPL_ISUPPORTS(FlyWebMDNSService,
- nsIDNSServiceDiscoveryListener,
- nsIDNSServiceResolveListener,
- nsIDNSRegistrationListener,
- nsITimerCallback)
-
-FlyWebMDNSService::FlyWebMDNSService(
- FlyWebService* aService,
- const nsACString& aServiceType)
- : mService(aService)
- , mServiceType(aServiceType)
- , mDiscoveryActive(false)
- , mNumConsecutiveStartDiscoveryFailures(0)
- , mDiscoveryState(DISCOVERY_IDLE)
-{}
-
-nsresult
-FlyWebMDNSService::OnDiscoveryStarted(const nsACString& aServiceType)
-{
- MOZ_ASSERT(mDiscoveryState == DISCOVERY_STARTING);
- mDiscoveryState = DISCOVERY_RUNNING;
- // Reset consecutive start discovery failures.
- mNumConsecutiveStartDiscoveryFailures = 0;
- LOG_I("===========================================");
- LOG_I("MDNSService::OnDiscoveryStarted(%s)", PromiseFlatCString(aServiceType).get());
- LOG_I("===========================================");
-
- // Clear the new service array.
- mNewServiceSet.Clear();
-
- // If service discovery is inactive, then stop network discovery immediately.
- if (!mDiscoveryActive) {
- // Set the stop timer to fire immediately.
- Unused << NS_WARN_IF(NS_FAILED(mDiscoveryStopTimer->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT)));
- return NS_OK;
- }
-
- // Otherwise, set the stop timer to fire in 5 seconds.
- Unused << NS_WARN_IF(NS_FAILED(mDiscoveryStopTimer->InitWithCallback(this, 5 * 1000, nsITimer::TYPE_ONE_SHOT)));
-
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::OnDiscoveryStopped(const nsACString& aServiceType)
-{
- LOG_I("///////////////////////////////////////////");
- LOG_I("MDNSService::OnDiscoveryStopped(%s)", PromiseFlatCString(aServiceType).get());
- LOG_I("///////////////////////////////////////////");
- MOZ_ASSERT(mDiscoveryState == DISCOVERY_STOPPING);
- mDiscoveryState = DISCOVERY_IDLE;
-
- // If service discovery is inactive, then discard all results and do not proceed.
- if (!mDiscoveryActive) {
- mServiceMap.Clear();
- mNewServiceSet.Clear();
- return NS_OK;
- }
-
- // Process the service map, add to the pair map.
- for (auto iter = mServiceMap.Iter(); !iter.Done(); iter.Next()) {
- DiscoveredInfo* service = iter.UserData();
-
- if (!mNewServiceSet.Contains(service->mService.mServiceId)) {
- iter.Remove();
- }
- }
-
- // Notify FlyWebService of changed service list.
- mService->NotifyDiscoveredServicesChanged();
-
- // Start discovery again immediately.
- Unused << NS_WARN_IF(NS_FAILED(mDiscoveryStartTimer->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT)));
-
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::OnServiceFound(nsIDNSServiceInfo* aServiceInfo)
-{
- LogDNSInfo(aServiceInfo, "FlyWebMDNSService::OnServiceFound");
-
- // If discovery is not active, don't do anything with the result.
- // If there is no discovery underway, ignore this.
- if (!mDiscoveryActive || mDiscoveryState != DISCOVERY_RUNNING) {
- return NS_OK;
- }
-
- // Discovery is underway - resolve the service.
- nsresult rv = mDNSServiceDiscovery->ResolveService(aServiceInfo, this);
- NS_ENSURE_SUCCESS(rv, rv);
-
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::OnServiceLost(nsIDNSServiceInfo* aServiceInfo)
-{
- LogDNSInfo(aServiceInfo, "FlyWebMDNSService::OnServiceLost");
-
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::OnStartDiscoveryFailed(const nsACString& aServiceType, int32_t aErrorCode)
-{
- LOG_E("MDNSService::OnStartDiscoveryFailed(%s): %d", PromiseFlatCString(aServiceType).get(), (int) aErrorCode);
-
- MOZ_ASSERT(mDiscoveryState == DISCOVERY_STARTING);
- mDiscoveryState = DISCOVERY_IDLE;
- mNumConsecutiveStartDiscoveryFailures++;
-
- // If discovery is active, and the number of consecutive failures is < 3, try starting again.
- if (mDiscoveryActive && mNumConsecutiveStartDiscoveryFailures < 3) {
- Unused << NS_WARN_IF(NS_FAILED(mDiscoveryStartTimer->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT)));
- }
-
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::OnStopDiscoveryFailed(const nsACString& aServiceType, int32_t aErrorCode)
-{
- LOG_E("MDNSService::OnStopDiscoveryFailed(%s)", PromiseFlatCString(aServiceType).get());
- MOZ_ASSERT(mDiscoveryState == DISCOVERY_STOPPING);
- mDiscoveryState = DISCOVERY_IDLE;
-
- // If discovery is active, start discovery again immediately.
- if (mDiscoveryActive) {
- Unused << NS_WARN_IF(NS_FAILED(mDiscoveryStartTimer->InitWithCallback(this, 0, nsITimer::TYPE_ONE_SHOT)));
- }
-
- return NS_OK;
-}
-
-static bool
-IsAcceptableServiceAddress(const nsCString& addr)
-{
- PRNetAddr prNetAddr;
- PRStatus status = PR_StringToNetAddr(addr.get(), &prNetAddr);
- if (status == PR_FAILURE) {
- return false;
- }
- // Only allow ipv4 addreses for now.
- return prNetAddr.raw.family == PR_AF_INET;
-}
-
-nsresult
-FlyWebMDNSService::OnServiceResolved(nsIDNSServiceInfo* aServiceInfo)
-{
- LogDNSInfo(aServiceInfo, "FlyWebMDNSService::OnServiceResolved");
-
- // If discovery is not active, don't do anything with the result.
- // If there is no discovery underway, ignore this resolve.
- if (!mDiscoveryActive || mDiscoveryState != DISCOVERY_RUNNING) {
- return NS_OK;
- }
-
- nsresult rv;
-
- nsCString address;
- rv = aServiceInfo->GetAddress(address);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- if (!IsAcceptableServiceAddress(address)) {
- return NS_OK;
- }
-
- // Create a new serviceInfo and stuff it in the new service array.
- UniquePtr<DiscoveredInfo> svc(new DiscoveredInfo(aServiceInfo));
- mNewServiceSet.PutEntry(svc->mService.mServiceId);
-
- DiscoveredInfo* existingSvc =
- mServiceMap.Get(svc->mService.mServiceId);
- if (existingSvc) {
- // Update the underlying DNS service info, but leave the old object in place.
- existingSvc->mDNSServiceInfo = aServiceInfo;
- } else {
- DiscoveredInfo* info = svc.release();
- mServiceMap.Put(info->mService.mServiceId, info);
- }
-
- // Notify FlyWebService of changed service list.
- mService->NotifyDiscoveredServicesChanged();
-
- return NS_OK;
-}
-
-FlyWebMDNSService::DiscoveredInfo::DiscoveredInfo(nsIDNSServiceInfo* aDNSServiceInfo)
- : mDNSServiceInfo(aDNSServiceInfo)
-{
- nsCString tmp;
- DebugOnly<nsresult> drv = aDNSServiceInfo->GetServiceName(tmp);
- MOZ_ASSERT(NS_SUCCEEDED(drv));
- CopyUTF8toUTF16(tmp, mService.mDisplayName);
-
- mService.mTransport = NS_LITERAL_STRING("mdns");
-
- drv = aDNSServiceInfo->GetServiceType(tmp);
- MOZ_ASSERT(NS_SUCCEEDED(drv));
- CopyUTF8toUTF16(tmp, mService.mServiceType);
-
- nsCOMPtr<nsIPropertyBag2> attrs;
- drv = aDNSServiceInfo->GetAttributes(getter_AddRefs(attrs));
- MOZ_ASSERT(NS_SUCCEEDED(drv));
- if (attrs) {
- attrs->GetPropertyAsAString(NS_LITERAL_STRING("cert"), mService.mCert);
- attrs->GetPropertyAsAString(NS_LITERAL_STRING("path"), mService.mPath);
- }
-
- // Construct a service id from the name, host, address, and port.
- nsCString cHost;
- drv = aDNSServiceInfo->GetHost(cHost);
- MOZ_ASSERT(NS_SUCCEEDED(drv));
-
- nsCString cAddress;
- drv = aDNSServiceInfo->GetAddress(cAddress);
- MOZ_ASSERT(NS_SUCCEEDED(drv));
-
- uint16_t port;
- drv = aDNSServiceInfo->GetPort(&port);
- MOZ_ASSERT(NS_SUCCEEDED(drv));
- nsAutoString portStr;
- portStr.AppendInt(port, 10);
-
- mService.mServiceId =
- NS_ConvertUTF8toUTF16(cAddress) +
- NS_LITERAL_STRING(":") +
- portStr +
- NS_LITERAL_STRING("|") +
- mService.mServiceType +
- NS_LITERAL_STRING("|") +
- NS_ConvertUTF8toUTF16(cHost) +
- NS_LITERAL_STRING("|") +
- mService.mDisplayName;
-}
-
-
-nsresult
-FlyWebMDNSService::OnResolveFailed(nsIDNSServiceInfo* aServiceInfo, int32_t aErrorCode)
-{
- LogDNSInfo(aServiceInfo, "FlyWebMDNSService::OnResolveFailed");
-
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::OnServiceRegistered(nsIDNSServiceInfo* aServiceInfo)
-{
- LogDNSInfo(aServiceInfo, "FlyWebMDNSService::OnServiceRegistered");
-
- nsCString cName;
- if (NS_WARN_IF(NS_FAILED(aServiceInfo->GetServiceName(cName)))) {
- return NS_ERROR_FAILURE;
- }
-
- nsString name = NS_ConvertUTF8toUTF16(cName);
- RefPtr<FlyWebPublishedServer> existingServer =
- FlyWebService::GetOrCreate()->FindPublishedServerByName(name);
- if (!existingServer) {
- return NS_ERROR_FAILURE;
- }
-
- existingServer->PublishedServerStarted(NS_OK);
-
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::OnServiceUnregistered(nsIDNSServiceInfo* aServiceInfo)
-{
- LogDNSInfo(aServiceInfo, "FlyWebMDNSService::OnServiceUnregistered");
-
- nsCString cName;
- if (NS_WARN_IF(NS_FAILED(aServiceInfo->GetServiceName(cName)))) {
- return NS_ERROR_FAILURE;
- }
-
- nsString name = NS_ConvertUTF8toUTF16(cName);
- RefPtr<FlyWebPublishedServer> existingServer =
- FlyWebService::GetOrCreate()->FindPublishedServerByName(name);
- if (!existingServer) {
- return NS_ERROR_FAILURE;
- }
-
- LOG_I("OnServiceRegistered(MDNS): De-advertised server with name %s.", cName.get());
-
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::OnRegistrationFailed(nsIDNSServiceInfo* aServiceInfo, int32_t errorCode)
-{
- LogDNSInfo(aServiceInfo, "FlyWebMDNSService::OnRegistrationFailed");
-
- nsCString cName;
- if (NS_WARN_IF(NS_FAILED(aServiceInfo->GetServiceName(cName)))) {
- return NS_ERROR_FAILURE;
- }
-
- nsString name = NS_ConvertUTF8toUTF16(cName);
- RefPtr<FlyWebPublishedServer> existingServer =
- 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->PublishedServerStarted(NS_ERROR_FAILURE);
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::OnUnregistrationFailed(nsIDNSServiceInfo* aServiceInfo, int32_t errorCode)
-{
- LogDNSInfo(aServiceInfo, "FlyWebMDNSService::OnUnregistrationFailed");
-
- nsCString cName;
- if (NS_WARN_IF(NS_FAILED(aServiceInfo->GetServiceName(cName)))) {
- return NS_ERROR_FAILURE;
- }
-
- nsString name = NS_ConvertUTF8toUTF16(cName);
- RefPtr<FlyWebPublishedServer> existingServer =
- FlyWebService::GetOrCreate()->FindPublishedServerByName(name);
- if (!existingServer) {
- return NS_ERROR_FAILURE;
- }
-
- LOG_I("OnServiceRegistered(MDNS): Un-Advertisement of server with name %s failed.", cName.get());
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::Notify(nsITimer* timer)
-{
- if (timer == mDiscoveryStopTimer.get()) {
- LOG_I("MDNSService::Notify() got discovery stop timeout");
- // Internet discovery stop timer has fired.
- nsresult rv = StopDiscovery();
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- return NS_OK;
- }
-
- if (timer == mDiscoveryStartTimer.get()) {
- LOG_I("MDNSService::Notify() got discovery start timeout");
- // Internet discovery start timer has fired.
- nsresult rv = StartDiscovery();
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
- return NS_OK;
- }
-
- LOG_E("MDNSService::Notify got unknown timeout.");
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::Init()
-{
- MOZ_ASSERT(mDiscoveryState == DISCOVERY_IDLE);
-
- mDiscoveryStartTimer = do_CreateInstance("@mozilla.org/timer;1");
- if (!mDiscoveryStartTimer) {
- return NS_ERROR_FAILURE;
- }
-
- mDiscoveryStopTimer = do_CreateInstance("@mozilla.org/timer;1");
- if (!mDiscoveryStopTimer) {
- return NS_ERROR_FAILURE;
- }
-
- nsresult rv;
- mDNSServiceDiscovery = do_GetService(DNSSERVICEDISCOVERY_CONTRACT_ID, &rv);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::StartDiscovery()
-{
- nsresult rv;
-
- // Always cancel the timer.
- rv = mDiscoveryStartTimer->Cancel();
- if (NS_WARN_IF(NS_FAILED(rv))) {
- LOG_E("FlyWeb failed to cancel DNS service discovery start timer.");
- }
-
- // If discovery is not idle, don't start it.
- if (mDiscoveryState != DISCOVERY_IDLE) {
- return NS_OK;
- }
-
- LOG_I("FlyWeb starting dicovery.");
- mDiscoveryState = DISCOVERY_STARTING;
-
- // start the discovery.
- rv = mDNSServiceDiscovery->StartDiscovery(mServiceType, this,
- getter_AddRefs(mCancelDiscovery));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- LOG_E("FlyWeb failed to start DNS service discovery.");
- return rv;
- }
-
- return NS_OK;
-}
-
-nsresult
-FlyWebMDNSService::StopDiscovery()
-{
- nsresult rv;
-
- // Always cancel the timer.
- rv = mDiscoveryStopTimer->Cancel();
- if (NS_WARN_IF(NS_FAILED(rv))) {
- LOG_E("FlyWeb failed to cancel DNS service discovery stop timer.");
- }
-
- // If discovery is not running, do nothing.
- if (mDiscoveryState != DISCOVERY_RUNNING) {
- return NS_OK;
- }
-
- LOG_I("FlyWeb stopping dicovery.");
-
- // Mark service discovery as stopping.
- mDiscoveryState = DISCOVERY_STOPPING;
-
- if (mCancelDiscovery) {
- LOG_I("MDNSService::StopDiscovery() - mCancelDiscovery exists!");
- nsCOMPtr<nsICancelable> cancelDiscovery = mCancelDiscovery.forget();
- rv = cancelDiscovery->Cancel(NS_ERROR_ABORT);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- LOG_E("FlyWeb failed to cancel DNS stop service discovery.");
- }
- } else {
- LOG_I("MDNSService::StopDiscovery() - mCancelDiscovery does not exist!");
- mDiscoveryState = DISCOVERY_IDLE;
- }
-
- return NS_OK;
-}
-
-void
-FlyWebMDNSService::ListDiscoveredServices(nsTArray<FlyWebDiscoveredService>& aServices)
-{
- for (auto iter = mServiceMap.Iter(); !iter.Done(); iter.Next()) {
- aServices.AppendElement(iter.UserData()->mService);
- }
-}
-
-bool
-FlyWebMDNSService::HasService(const nsAString& aServiceId)
-{
- return mServiceMap.Contains(aServiceId);
-}
-
-nsresult
-FlyWebMDNSService::PairWithService(const nsAString& aServiceId,
- UniquePtr<FlyWebService::PairedInfo>& aInfo)
-{
- MOZ_ASSERT(HasService(aServiceId));
-
- nsresult rv;
- nsCOMPtr<nsIUUIDGenerator> uuidgen =
- do_GetService("@mozilla.org/uuid-generator;1", &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsID id;
- rv = uuidgen->GenerateUUIDInPlace(&id);
- NS_ENSURE_SUCCESS(rv, rv);
-
- aInfo.reset(new FlyWebService::PairedInfo());
-
- char uuidChars[NSID_LENGTH];
- id.ToProvidedString(uuidChars);
- CopyUTF8toUTF16(Substring(uuidChars + 1, uuidChars + NSID_LENGTH - 2),
- aInfo->mService.mHostname);
-
- DiscoveredInfo* discInfo = mServiceMap.Get(aServiceId);
-
- nsAutoString url;
- if (discInfo->mService.mCert.IsEmpty()) {
- url.AssignLiteral("http://");
- } else {
- url.AssignLiteral("https://");
- }
- url.Append(aInfo->mService.mHostname + NS_LITERAL_STRING("/"));
- nsCOMPtr<nsIURI> uiURL;
- NS_NewURI(getter_AddRefs(uiURL), url);
- MOZ_ASSERT(uiURL);
- if (!discInfo->mService.mPath.IsEmpty()) {
- nsCOMPtr<nsIURI> tmp = uiURL.forget();
- NS_NewURI(getter_AddRefs(uiURL), discInfo->mService.mPath, nullptr, tmp);
- }
- if (uiURL) {
- nsAutoCString spec;
- uiURL->GetSpec(spec);
- CopyUTF8toUTF16(spec, aInfo->mService.mUiUrl);
- }
-
- aInfo->mService.mDiscoveredService = discInfo->mService;
- aInfo->mDNSServiceInfo = discInfo->mDNSServiceInfo;
-
- return NS_OK;
-}
-
-nsresult
-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());
-
- serviceInfo->SetPort(aServer->Port());
- serviceInfo->SetServiceType(mServiceType);
-
- nsCString certKey;
- aServer->GetCertKey(certKey);
- nsString uiURL;
- aServer->GetUiUrl(uiURL);
-
- if (!uiURL.IsEmpty() || !certKey.IsEmpty()) {
- RefPtr<nsHashPropertyBag> attrs = new nsHashPropertyBag();
- if (!uiURL.IsEmpty()) {
- attrs->SetPropertyAsAString(NS_LITERAL_STRING("path"), uiURL);
- }
- if (!certKey.IsEmpty()) {
- attrs->SetPropertyAsACString(NS_LITERAL_STRING("cert"), certKey);
- }
- serviceInfo->SetAttributes(attrs);
- }
-
- nsCString cstrName = NS_ConvertUTF16toUTF8(aServer->Name());
- LOG_I("MDNSService::StartDiscoveryOf() advertising service %s", cstrName.get());
- serviceInfo->SetServiceName(cstrName);
-
- LogDNSInfo(serviceInfo, "FlyWebMDNSService::StartDiscoveryOf");
-
- // Advertise the service.
- nsCOMPtr<nsICancelable> cancelRegister;
- nsresult rv = mDNSServiceDiscovery->
- RegisterService(serviceInfo, this, getter_AddRefs(cancelRegister));
- NS_ENSURE_SUCCESS(rv, rv);
-
- // All done.
- aServer->SetCancelRegister(cancelRegister);
-
- return NS_OK;
-}
-
-void
-FlyWebMDNSService::EnsureDiscoveryStarted()
-{
- mDiscoveryActive = true;
- // If state is idle, start discovery immediately.
- if (mDiscoveryState == DISCOVERY_IDLE) {
- StartDiscovery();
- }
-}
-
-void
-FlyWebMDNSService::EnsureDiscoveryStopped()
-{
- // All we need to do is set the flag to false.
- // If current state is IDLE, it's already the correct state.
- // Otherwise, the handlers for the internal state
- // transitions will check this flag and drive the state
- // towards IDLE.
- mDiscoveryActive = false;
-}
-
-static StaticRefPtr<FlyWebService> gFlyWebService;
-
-NS_IMPL_ISUPPORTS(FlyWebService, nsIObserver)
-
-FlyWebService::FlyWebService()
- : mMonitor("FlyWebService::mMonitor")
-{
- MOZ_ASSERT(NS_IsMainThread());
- nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
- if (obs) {
- obs->AddObserver(this, "inner-window-destroyed", false);
- }
-}
-
-FlyWebService::~FlyWebService()
-{
-}
-
-FlyWebService*
-FlyWebService::GetExisting()
-{
- return gFlyWebService;
-}
-
-FlyWebService*
-FlyWebService::GetOrCreate()
-{
- if (!gFlyWebService) {
- gFlyWebService = new FlyWebService();
- ClearOnShutdown(&gFlyWebService);
- ErrorResult rv = gFlyWebService->Init();
- if (rv.Failed()) {
- gFlyWebService = nullptr;
- return nullptr;
- }
- }
- 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.");
- mMDNSHttpService = nullptr;
- rv.SuppressException();
- }
- }
-
- if (!mMDNSFlywebService) {
- mMDNSFlywebService = new FlyWebMDNSService(this, NS_LITERAL_CSTRING("_flyweb._tcp."));
- ErrorResult rv;
-
- rv = mMDNSFlywebService->Init();
- if (rv.Failed()) {
- LOG_E("FlyWebService failed to initialize MDNS _flyweb._tcp.");
- mMDNSFlywebService = nullptr;
- rv.SuppressException();
- }
- }
-
- return ErrorResult(NS_OK);
-}
-
-static already_AddRefed<FlyWebPublishPromise>
-MakeRejectionPromise(const char* name)
-{
- MozPromiseHolder<FlyWebPublishPromise> holder;
- RefPtr<FlyWebPublishPromise> promise = holder.Ensure(name);
- holder.Reject(NS_ERROR_FAILURE, name);
- return promise.forget();
-}
-
-static bool
-CheckForFlyWebAddon(const nsACString& uriString)
-{
- // Before proceeding, ensure that the FlyWeb system addon exists.
- nsresult rv;
- nsCOMPtr<nsIURI> uri;
- rv = NS_NewURI(getter_AddRefs(uri), uriString);
- if (NS_FAILED(rv)) {
- return false;
- }
-
- JSAddonId *addonId = MapURIToAddonID(uri);
- if (!addonId) {
- return false;
- }
-
- JSFlatString* flat = JS_ASSERT_STRING_IS_FLAT(JS::StringOfAddonId(addonId));
- nsAutoString addonIdString;
- AssignJSFlatString(addonIdString, flat);
- if (!addonIdString.EqualsLiteral("flyweb@mozilla.org")) {
- nsCString addonIdCString = NS_ConvertUTF16toUTF8(addonIdString);
- return false;
- }
-
- return true;
-}
-
-already_AddRefed<FlyWebPublishPromise>
-FlyWebService::PublishServer(const nsAString& aName,
- const FlyWebPublishOptions& aOptions,
- nsPIDOMWindowInner* aWindow)
-{
- // 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());
- return MakeRejectionPromise(__func__);
- }
-
- RefPtr<FlyWebPublishedServer> server;
- if (XRE_GetProcessType() == GeckoProcessType_Content) {
- server = new FlyWebPublishedServerChild(aWindow, aName, aOptions);
- } else {
- server = new FlyWebPublishedServerImpl(aWindow, aName, aOptions);
-
- // Before proceeding, ensure that the FlyWeb system addon exists.
- if (!CheckForFlyWebAddon(NS_LITERAL_CSTRING("chrome://flyweb/skin/icon-64.png")) &&
- !CheckForFlyWebAddon(NS_LITERAL_CSTRING("chrome://flyweb/content/icon-64.png")))
- {
- LOG_E("PublishServer: Failed to find FlyWeb system addon.");
- return MakeRejectionPromise(__func__);
- }
- }
-
- if (aWindow) {
- nsresult rv;
-
- MOZ_ASSERT(NS_IsMainThread());
- rv = NS_DispatchToCurrentThread(
- MakeAndAddRef<FlyWebPublishServerPermissionCheck>(
- NS_ConvertUTF16toUTF8(aName), aWindow->WindowID(), server));
- if (NS_WARN_IF(NS_FAILED(rv))) {
- LOG_E("PublishServer: Failed to dispatch permission check runnable for %s",
- NS_ConvertUTF16toUTF8(aName).get());
- return MakeRejectionPromise(__func__);
- }
- } else {
- // If aWindow is null, we're definitely in the e10s parent process.
- // In this case, we know that permission has already been granted
- // by the user because of content-process prompt.
- MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
- server->PermissionGranted(true);
- }
-
- mServers.AppendElement(server);
-
- return server->GetPublishPromise();
-}
-
-already_AddRefed<FlyWebPublishedServer>
-FlyWebService::FindPublishedServerByName(
- const nsAString& aName)
-{
- MOZ_ASSERT(NS_IsMainThread());
- for (FlyWebPublishedServer* publishedServer : mServers) {
- if (publishedServer->Name().Equals(aName)) {
- RefPtr<FlyWebPublishedServer> server = publishedServer;
- return server.forget();
- }
- }
- return nullptr;
-}
-
-void
-FlyWebService::RegisterDiscoveryManager(FlyWebDiscoveryManager* aDiscoveryManager)
-{
- MOZ_ASSERT(NS_IsMainThread());
- mDiscoveryManagerTable.PutEntry(aDiscoveryManager);
- if (mMDNSHttpService) {
- mMDNSHttpService->EnsureDiscoveryStarted();
- }
- if (mMDNSFlywebService) {
- mMDNSFlywebService->EnsureDiscoveryStarted();
- }
-}
-
-void
-FlyWebService::UnregisterDiscoveryManager(FlyWebDiscoveryManager* aDiscoveryManager)
-{
- MOZ_ASSERT(NS_IsMainThread());
- mDiscoveryManagerTable.RemoveEntry(aDiscoveryManager);
- if (mDiscoveryManagerTable.IsEmpty()) {
- if (mMDNSHttpService) {
- mMDNSHttpService->EnsureDiscoveryStopped();
- }
- if (mMDNSFlywebService) {
- mMDNSFlywebService->EnsureDiscoveryStopped();
- }
- }
-}
-
-NS_IMETHODIMP
-FlyWebService::Observe(nsISupports* aSubject, const char* aTopic,
- const char16_t* aData)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (strcmp(aTopic, "inner-window-destroyed")) {
- return NS_OK;
- }
-
- nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
- NS_ENSURE_TRUE(wrapper, NS_ERROR_FAILURE);
-
- uint64_t innerID;
- nsresult rv = wrapper->GetData(&innerID);
- NS_ENSURE_SUCCESS(rv, rv);
-
- for (FlyWebPublishedServer* server : mServers) {
- if (server->OwnerWindowID() == innerID) {
- server->Close();
- }
- }
-
- return NS_OK;
-}
-
-void
-FlyWebService::UnregisterServer(FlyWebPublishedServer* aServer)
-{
- MOZ_ASSERT(NS_IsMainThread());
- DebugOnly<bool> removed = mServers.RemoveElement(aServer);
- MOZ_ASSERT(removed);
-}
-
-bool
-FlyWebService::HasConnectionOrServer(uint64_t aWindowID)
-{
- MOZ_ASSERT(NS_IsMainThread());
- for (FlyWebPublishedServer* server : mServers) {
- nsPIDOMWindowInner* win = server->GetOwner();
- if (win && win->WindowID() == aWindowID) {
- return true;
- }
- }
-
- return false;
-}
-
-void
-FlyWebService::NotifyDiscoveredServicesChanged()
-{
- // Process the service map, add to the pair map.
- for (auto iter = mDiscoveryManagerTable.Iter(); !iter.Done(); iter.Next()) {
- iter.Get()->GetKey()->NotifyDiscoveredServicesChanged();
- }
-}
-
-void
-FlyWebService::ListDiscoveredServices(nsTArray<FlyWebDiscoveredService>& aServices)
-{
- MOZ_ASSERT(NS_IsMainThread());
- if (mMDNSHttpService) {
- mMDNSHttpService->ListDiscoveredServices(aServices);
- }
- if (mMDNSFlywebService) {
- mMDNSFlywebService->ListDiscoveredServices(aServices);
- }
-}
-
-void
-FlyWebService::PairWithService(const nsAString& aServiceId,
- FlyWebPairingCallback& aCallback)
-{
- MOZ_ASSERT(NS_IsMainThread());
- // See if we have already paired with this service. If so, re-use the
- // FlyWebPairedService for that.
- {
- ReentrantMonitorAutoEnter pairedMapLock(mMonitor);
- for (auto iter = mPairedServiceTable.Iter(); !iter.Done(); iter.Next()) {
- PairedInfo* pairInfo = iter.UserData();
- if (pairInfo->mService.mDiscoveredService.mServiceId.Equals(aServiceId)) {
- ErrorResult er;
- ReentrantMonitorAutoExit pairedMapRelease(mMonitor);
- aCallback.PairingSucceeded(pairInfo->mService, er);
- ENSURE_SUCCESS_VOID(er);
- return;
- }
- }
- }
-
- UniquePtr<PairedInfo> pairInfo;
-
- nsresult rv = NS_OK;
- bool notFound = false;
- if (mMDNSHttpService && mMDNSHttpService->HasService(aServiceId)) {
- rv = mMDNSHttpService->PairWithService(aServiceId, pairInfo);
- } else if (mMDNSFlywebService && mMDNSFlywebService->HasService(aServiceId)) {
- rv = mMDNSFlywebService->PairWithService(aServiceId, pairInfo);
- } else {
- notFound = true;
- }
-
- if (NS_FAILED(rv)) {
- ErrorResult result;
- result.Throw(rv);
- const nsAString& reason = NS_LITERAL_STRING("Error pairing.");
- aCallback.PairingFailed(reason, result);
- ENSURE_SUCCESS_VOID(result);
- return;
- }
-
- if (!pairInfo) {
- ErrorResult res;
- const nsAString& reason = notFound ?
- NS_LITERAL_STRING("No such service.") :
- NS_LITERAL_STRING("Error pairing.");
- aCallback.PairingFailed(reason, res);
- ENSURE_SUCCESS_VOID(res);
- return;
- }
-
- // Add fingerprint to certificate override database.
- if (!pairInfo->mService.mDiscoveredService.mCert.IsEmpty()) {
- nsCOMPtr<nsICertOverrideService> override =
- do_GetService("@mozilla.org/security/certoverride;1");
- if (!override ||
- NS_FAILED(override->RememberTemporaryValidityOverrideUsingFingerprint(
- NS_ConvertUTF16toUTF8(pairInfo->mService.mHostname),
- -1,
- NS_ConvertUTF16toUTF8(pairInfo->mService.mDiscoveredService.mCert),
- nsICertOverrideService::ERROR_UNTRUSTED |
- nsICertOverrideService::ERROR_MISMATCH))) {
- ErrorResult res;
- aCallback.PairingFailed(NS_LITERAL_STRING("Error adding certificate override."), res);
- ENSURE_SUCCESS_VOID(res);
- return;
- }
- }
-
- // Grab a weak reference to the PairedInfo so that we can
- // use it even after ownership has been transferred to mPairedServiceTable
- PairedInfo* pairInfoWeak = pairInfo.release();
-
- {
- ReentrantMonitorAutoEnter pairedMapLock(mMonitor);
- mPairedServiceTable.Put(
- NS_ConvertUTF16toUTF8(pairInfoWeak->mService.mHostname), pairInfoWeak);
- }
-
- ErrorResult er;
- aCallback.PairingSucceeded(pairInfoWeak->mService, er);
- ENSURE_SUCCESS_VOID(er);
-}
-
-nsresult
-FlyWebService::CreateTransportForHost(const char **types,
- uint32_t typeCount,
- const nsACString &host,
- int32_t port,
- const nsACString &hostRoute,
- int32_t portRoute,
- nsIProxyInfo *proxyInfo,
- nsISocketTransport **result)
-{
- // This might be called on background threads
-
- *result = nullptr;
-
- nsCString ipAddrString;
- uint16_t discPort;
-
- {
- ReentrantMonitorAutoEnter pairedMapLock(mMonitor);
-
- PairedInfo* info = mPairedServiceTable.Get(host);
-
- if (!info) {
- return NS_OK;
- }
-
- // Get the ip address of the underlying service.
- info->mDNSServiceInfo->GetAddress(ipAddrString);
- info->mDNSServiceInfo->GetPort(&discPort);
- }
-
- // Parse it into an NetAddr.
- PRNetAddr prNetAddr;
- PRStatus status = PR_StringToNetAddr(ipAddrString.get(), &prNetAddr);
- NS_ENSURE_FALSE(status == PR_FAILURE, NS_ERROR_FAILURE);
-
- // Convert PRNetAddr to NetAddr.
- mozilla::net::NetAddr netAddr;
- PRNetAddrToNetAddr(&prNetAddr, &netAddr);
- netAddr.inet.port = htons(discPort);
-
- RefPtr<mozilla::net::nsSocketTransport> trans = new mozilla::net::nsSocketTransport();
- nsresult rv = trans->InitPreResolved(
- types, typeCount, host, port, hostRoute, portRoute, proxyInfo, &netAddr);
- NS_ENSURE_SUCCESS(rv, rv);
-
- trans.forget(result);
- return NS_OK;
-}
-
-void
-FlyWebService::StartDiscoveryOf(FlyWebPublishedServerImpl* aServer)
-{
- MOZ_ASSERT(NS_IsMainThread());
- nsresult rv = mMDNSFlywebService ?
- mMDNSFlywebService->StartDiscoveryOf(aServer) :
- NS_ERROR_FAILURE;
-
- if (NS_FAILED(rv)) {
- aServer->PublishedServerStarted(rv);
- }
-}
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/flyweb/FlyWebService.h b/dom/flyweb/FlyWebService.h
deleted file mode 100644
index f7b983440..000000000
--- a/dom/flyweb/FlyWebService.h
+++ /dev/null
@@ -1,113 +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/. */
-
-#ifndef mozilla_dom_FlyWebService_h
-#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 {
-
-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<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,
- uint32_t typeCount,
- const nsACString &host,
- int32_t port,
- const nsACString &hostRoute,
- int32_t portRoute,
- nsIProxyInfo *proxyInfo,
- nsISocketTransport **result);
-
- already_AddRefed<FlyWebPublishedServer> FindPublishedServerByName(
- const nsAString& aName);
-
- void RegisterDiscoveryManager(FlyWebDiscoveryManager* aDiscoveryManager);
- void UnregisterDiscoveryManager(FlyWebDiscoveryManager* aDiscoveryManager);
-
- // Should only be called by FlyWebPublishedServerImpl
- void StartDiscoveryOf(FlyWebPublishedServerImpl* aServer);
-
-private:
- FlyWebService();
- ~FlyWebService();
-
- ErrorResult Init();
-
- void NotifyDiscoveredServicesChanged();
-
- // Might want to make these hashes for perf
- nsTArray<FlyWebPublishedServer*> mServers;
-
- RefPtr<FlyWebMDNSService> mMDNSHttpService;
- RefPtr<FlyWebMDNSService> mMDNSFlywebService;
-
- struct PairedInfo
- {
- FlyWebPairedService mService;
- nsCOMPtr<nsIDNSServiceInfo> mDNSServiceInfo;
- };
- nsClassHashtable<nsCStringHashKey, PairedInfo>
- mPairedServiceTable;
- ReentrantMonitor mMonitor; // Protecting mPairedServiceTable
-
- nsTHashtable<nsPtrHashKey<FlyWebDiscoveryManager>> mDiscoveryManagerTable;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_FlyWebService_h
diff --git a/dom/flyweb/HttpServer.cpp b/dom/flyweb/HttpServer.cpp
deleted file mode 100644
index 26e15d9d5..000000000
--- a/dom/flyweb/HttpServer.cpp
+++ /dev/null
@@ -1,1319 +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/HttpServer.h"
-#include "nsISocketTransport.h"
-#include "nsWhitespaceTokenizer.h"
-#include "nsNetUtil.h"
-#include "nsIStreamTransportService.h"
-#include "nsIAsyncStreamCopier2.h"
-#include "nsIPipe.h"
-#include "nsIOService.h"
-#include "nsIHttpChannelInternal.h"
-#include "Base64.h"
-#include "WebSocketChannel.h"
-#include "nsCharSeparatedTokenizer.h"
-#include "nsIX509Cert.h"
-
-static NS_DEFINE_CID(kStreamTransportServiceCID, NS_STREAMTRANSPORTSERVICE_CID);
-
-namespace mozilla {
-namespace dom {
-
-static LazyLogModule gHttpServerLog("HttpServer");
-#undef LOG_I
-#define LOG_I(...) MOZ_LOG(gHttpServerLog, mozilla::LogLevel::Debug, (__VA_ARGS__))
-#undef LOG_V
-#define LOG_V(...) MOZ_LOG(gHttpServerLog, mozilla::LogLevel::Verbose, (__VA_ARGS__))
-#undef LOG_E
-#define LOG_E(...) MOZ_LOG(gHttpServerLog, mozilla::LogLevel::Error, (__VA_ARGS__))
-
-
-NS_IMPL_ISUPPORTS(HttpServer,
- nsIServerSocketListener,
- nsILocalCertGetCallback)
-
-HttpServer::HttpServer()
- : mPort()
- , mHttps()
-{
-}
-
-HttpServer::~HttpServer()
-{
-}
-
-void
-HttpServer::Init(int32_t aPort, bool aHttps, HttpServerListener* aListener)
-{
- mPort = aPort;
- mHttps = aHttps;
- mListener = aListener;
-
- if (mHttps) {
- nsCOMPtr<nsILocalCertService> lcs =
- do_CreateInstance("@mozilla.org/security/local-cert-service;1");
- nsresult rv = lcs->GetOrCreateCert(NS_LITERAL_CSTRING("flyweb"), this);
- if (NS_FAILED(rv)) {
- NotifyStarted(rv);
- }
- } else {
- // Make sure to always have an async step before notifying callbacks
- HandleCert(nullptr, NS_OK);
- }
-}
-
-NS_IMETHODIMP
-HttpServer::HandleCert(nsIX509Cert* aCert, nsresult aResult)
-{
- nsresult rv = aResult;
- if (NS_SUCCEEDED(rv)) {
- rv = StartServerSocket(aCert);
- }
-
- if (NS_FAILED(rv) && mServerSocket) {
- mServerSocket->Close();
- mServerSocket = nullptr;
- }
-
- NotifyStarted(rv);
-
- return NS_OK;
-}
-
-void
-HttpServer::NotifyStarted(nsresult aStatus)
-{
- RefPtr<HttpServerListener> listener = mListener;
- nsCOMPtr<nsIRunnable> event = NS_NewRunnableFunction([listener, aStatus] ()
- {
- listener->OnServerStarted(aStatus);
- });
- NS_DispatchToCurrentThread(event);
-}
-
-nsresult
-HttpServer::StartServerSocket(nsIX509Cert* aCert)
-{
- nsresult rv;
- mServerSocket =
- do_CreateInstance(aCert ? "@mozilla.org/network/tls-server-socket;1"
- : "@mozilla.org/network/server-socket;1", &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = mServerSocket->Init(mPort, false, -1);
- NS_ENSURE_SUCCESS(rv, rv);
-
- if (aCert) {
- nsCOMPtr<nsITLSServerSocket> tls = do_QueryInterface(mServerSocket);
- rv = tls->SetServerCert(aCert);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = tls->SetSessionTickets(false);
- NS_ENSURE_SUCCESS(rv, rv);
-
- mCert = aCert;
- }
-
- rv = mServerSocket->AsyncListen(this);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = mServerSocket->GetPort(&mPort);
- NS_ENSURE_SUCCESS(rv, rv);
-
- LOG_I("HttpServer::StartServerSocket(%p)", this);
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-HttpServer::OnSocketAccepted(nsIServerSocket* aServ,
- nsISocketTransport* aTransport)
-{
- MOZ_ASSERT(SameCOMIdentity(aServ, mServerSocket));
-
- nsresult rv;
- RefPtr<Connection> conn = new Connection(aTransport, this, rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- LOG_I("HttpServer::OnSocketAccepted(%p) - Socket %p", this, conn.get());
-
- mConnections.AppendElement(conn.forget());
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-HttpServer::OnStopListening(nsIServerSocket* aServ,
- nsresult aStatus)
-{
- MOZ_ASSERT(aServ == mServerSocket || !mServerSocket);
-
- LOG_I("HttpServer::OnStopListening(%p) - status 0x%lx", this, aStatus);
-
- Close();
-
- return NS_OK;
-}
-
-void
-HttpServer::SendResponse(InternalRequest* aRequest, InternalResponse* aResponse)
-{
- for (Connection* conn : mConnections) {
- if (conn->TryHandleResponse(aRequest, aResponse)) {
- return;
- }
- }
-
- MOZ_ASSERT(false, "Unknown request");
-}
-
-already_AddRefed<nsITransportProvider>
-HttpServer::AcceptWebSocket(InternalRequest* aConnectRequest,
- const Optional<nsAString>& aProtocol,
- ErrorResult& aRv)
-{
- for (Connection* conn : mConnections) {
- if (!conn->HasPendingWebSocketRequest(aConnectRequest)) {
- continue;
- }
- nsCOMPtr<nsITransportProvider> provider =
- conn->HandleAcceptWebSocket(aProtocol, aRv);
- if (aRv.Failed()) {
- conn->Close();
- }
- // This connection is now owned by the websocket, or we just closed it
- mConnections.RemoveElement(conn);
- return provider.forget();
- }
-
- aRv.Throw(NS_ERROR_UNEXPECTED);
- MOZ_ASSERT(false, "Unknown request");
-
- return nullptr;
-}
-
-void
-HttpServer::SendWebSocketResponse(InternalRequest* aConnectRequest,
- InternalResponse* aResponse)
-{
- for (Connection* conn : mConnections) {
- if (conn->HasPendingWebSocketRequest(aConnectRequest)) {
- conn->HandleWebSocketResponse(aResponse);
- return;
- }
- }
-
- MOZ_ASSERT(false, "Unknown request");
-}
-
-void
-HttpServer::Close()
-{
- if (mServerSocket) {
- mServerSocket->Close();
- mServerSocket = nullptr;
- }
-
- if (mListener) {
- RefPtr<HttpServerListener> listener = mListener.forget();
- listener->OnServerClose();
- }
-
- for (Connection* conn : mConnections) {
- conn->Close();
- }
- mConnections.Clear();
-}
-
-void
-HttpServer::GetCertKey(nsACString& aKey)
-{
- nsAutoString tmp;
- if (mCert) {
- mCert->GetSha256Fingerprint(tmp);
- }
- LossyCopyUTF16toASCII(tmp, aKey);
-}
-
-NS_IMPL_ISUPPORTS(HttpServer::TransportProvider,
- nsITransportProvider)
-
-HttpServer::TransportProvider::~TransportProvider()
-{
-}
-
-NS_IMETHODIMP
-HttpServer::TransportProvider::SetListener(nsIHttpUpgradeListener* aListener)
-{
- MOZ_ASSERT(!mListener);
- MOZ_ASSERT(aListener);
-
- mListener = aListener;
-
- MaybeNotify();
-
- return NS_OK;
-}
-
-NS_IMETHODIMP
-HttpServer::TransportProvider::GetIPCChild(PTransportProviderChild** aChild)
-{
- MOZ_CRASH("Don't call this in parent process");
- *aChild = nullptr;
- return NS_OK;
-}
-
-void
-HttpServer::TransportProvider::SetTransport(nsISocketTransport* aTransport,
- nsIAsyncInputStream* aInput,
- nsIAsyncOutputStream* aOutput)
-{
- MOZ_ASSERT(!mTransport);
- MOZ_ASSERT(aTransport && aInput && aOutput);
-
- mTransport = aTransport;
- mInput = aInput;
- mOutput = aOutput;
-
- MaybeNotify();
-}
-
-void
-HttpServer::TransportProvider::MaybeNotify()
-{
- if (mTransport && mListener) {
- RefPtr<TransportProvider> self = this;
- nsCOMPtr<nsIRunnable> event = NS_NewRunnableFunction([self, this] ()
- {
- mListener->OnTransportAvailable(mTransport, mInput, mOutput);
- });
- NS_DispatchToCurrentThread(event);
- }
-}
-
-NS_IMPL_ISUPPORTS(HttpServer::Connection,
- nsIInputStreamCallback,
- nsIOutputStreamCallback)
-
-HttpServer::Connection::Connection(nsISocketTransport* aTransport,
- HttpServer* aServer,
- nsresult& rv)
- : mServer(aServer)
- , mTransport(aTransport)
- , mState(eRequestLine)
- , mPendingReqVersion()
- , mRemainingBodySize()
- , mCloseAfterRequest(false)
-{
- nsCOMPtr<nsIInputStream> input;
- rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(input));
- NS_ENSURE_SUCCESS_VOID(rv);
-
- mInput = do_QueryInterface(input);
-
- nsCOMPtr<nsIOutputStream> output;
- rv = mTransport->OpenOutputStream(0, 0, 0, getter_AddRefs(output));
- NS_ENSURE_SUCCESS_VOID(rv);
-
- mOutput = do_QueryInterface(output);
-
- if (mServer->mHttps) {
- SetSecurityObserver(true);
- } else {
- mInput->AsyncWait(this, 0, 0, NS_GetCurrentThread());
- }
-}
-
-NS_IMETHODIMP
-HttpServer::Connection::OnHandshakeDone(nsITLSServerSocket* aServer,
- nsITLSClientStatus* aStatus)
-{
- LOG_I("HttpServer::Connection::OnHandshakeDone(%p)", this);
-
- // XXX Verify connection security
-
- SetSecurityObserver(false);
- mInput->AsyncWait(this, 0, 0, NS_GetCurrentThread());
-
- return NS_OK;
-}
-
-void
-HttpServer::Connection::SetSecurityObserver(bool aListen)
-{
- LOG_I("HttpServer::Connection::SetSecurityObserver(%p) - %s", this,
- aListen ? "On" : "Off");
-
- nsCOMPtr<nsISupports> secInfo;
- mTransport->GetSecurityInfo(getter_AddRefs(secInfo));
- nsCOMPtr<nsITLSServerConnectionInfo> tlsConnInfo =
- do_QueryInterface(secInfo);
- MOZ_ASSERT(tlsConnInfo);
- tlsConnInfo->SetSecurityObserver(aListen ? this : nullptr);
-}
-
-HttpServer::Connection::~Connection()
-{
-}
-
-NS_IMETHODIMP
-HttpServer::Connection::OnInputStreamReady(nsIAsyncInputStream* aStream)
-{
- MOZ_ASSERT(!mInput || aStream == mInput);
-
- LOG_I("HttpServer::Connection::OnInputStreamReady(%p)", this);
-
- if (!mInput || mState == ePause) {
- return NS_OK;
- }
-
- uint64_t avail;
- nsresult rv = mInput->Available(&avail);
- if (NS_FAILED(rv)) {
- LOG_I("HttpServer::Connection::OnInputStreamReady(%p) - Connection closed", this);
-
- mServer->mConnections.RemoveElement(this);
- // Connection closed. Handle errors here.
- return NS_OK;
- }
-
- uint32_t numRead;
- rv = mInput->ReadSegments(ReadSegmentsFunc,
- this,
- UINT32_MAX,
- &numRead);
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = mInput->AsyncWait(this, 0, 0, NS_GetCurrentThread());
- NS_ENSURE_SUCCESS(rv, rv);
-
- return NS_OK;
-}
-
-nsresult
-HttpServer::Connection::ReadSegmentsFunc(nsIInputStream* aIn,
- void* aClosure,
- const char* aBuffer,
- uint32_t aToOffset,
- uint32_t aCount,
- uint32_t* aWriteCount)
-{
- const char* buffer = aBuffer;
- nsresult rv = static_cast<HttpServer::Connection*>(aClosure)->
- ConsumeInput(buffer, buffer + aCount);
-
- *aWriteCount = buffer - aBuffer;
- MOZ_ASSERT(*aWriteCount <= aCount);
-
- return rv;
-}
-
-static const char*
-findCRLF(const char* aBuffer, const char* aEnd)
-{
- if (aBuffer + 1 >= aEnd) {
- return nullptr;
- }
-
- const char* pos;
- while ((pos = static_cast<const char*>(memchr(aBuffer,
- '\r',
- aEnd - aBuffer - 1)))) {
- if (*(pos + 1) == '\n') {
- return pos;
- }
- aBuffer = pos + 1;
- }
- return nullptr;
-}
-
-nsresult
-HttpServer::Connection::ConsumeInput(const char*& aBuffer,
- const char* aEnd)
-{
- nsresult rv;
- while (mState == eRequestLine ||
- mState == eHeaders) {
- // Consume line-by-line
-
- // Check if buffer boundry ended up right between the CR and LF
- if (!mInputBuffer.IsEmpty() && mInputBuffer.Last() == '\r' &&
- *aBuffer == '\n') {
- aBuffer++;
- rv = ConsumeLine(mInputBuffer.BeginReading(), mInputBuffer.Length() - 1);
- NS_ENSURE_SUCCESS(rv, rv);
-
- mInputBuffer.Truncate();
- }
-
- // Look for a CRLF
- const char* pos = findCRLF(aBuffer, aEnd);
- if (!pos) {
- mInputBuffer.Append(aBuffer, aEnd - aBuffer);
- aBuffer = aEnd;
- return NS_OK;
- }
-
- if (!mInputBuffer.IsEmpty()) {
- mInputBuffer.Append(aBuffer, pos - aBuffer);
- aBuffer = pos + 2;
- rv = ConsumeLine(mInputBuffer.BeginReading(), mInputBuffer.Length() - 1);
- NS_ENSURE_SUCCESS(rv, rv);
-
- mInputBuffer.Truncate();
- } else {
- rv = ConsumeLine(aBuffer, pos - aBuffer);
- NS_ENSURE_SUCCESS(rv, rv);
-
- aBuffer = pos + 2;
- }
- }
-
- if (mState == eBody) {
- uint32_t size = std::min(mRemainingBodySize,
- static_cast<uint32_t>(aEnd - aBuffer));
- uint32_t written = size;
-
- if (mCurrentRequestBody) {
- rv = mCurrentRequestBody->Write(aBuffer, size, &written);
- // Since we've given the pipe unlimited size, we should never
- // end up needing to block.
- MOZ_ASSERT(rv != NS_BASE_STREAM_WOULD_BLOCK);
- if (NS_FAILED(rv)) {
- written = size;
- mCurrentRequestBody = nullptr;
- }
- }
-
- aBuffer += written;
- mRemainingBodySize -= written;
- if (!mRemainingBodySize) {
- mCurrentRequestBody->Close();
- mCurrentRequestBody = nullptr;
- mState = eRequestLine;
- }
- }
-
- return NS_OK;
-}
-
-bool
-ContainsToken(const nsCString& aList, const nsCString& aToken)
-{
- nsCCharSeparatedTokenizer tokens(aList, ',');
- bool found = false;
- while (!found && tokens.hasMoreTokens()) {
- found = tokens.nextToken().Equals(aToken);
- }
- return found;
-}
-
-static bool
-IsWebSocketRequest(InternalRequest* aRequest, uint32_t aHttpVersion)
-{
- if (aHttpVersion < 1) {
- return false;
- }
-
- nsAutoCString str;
- aRequest->GetMethod(str);
- if (!str.EqualsLiteral("GET")) {
- return false;
- }
-
- InternalHeaders* headers = aRequest->Headers();
- ErrorResult res;
-
- headers->GetFirst(NS_LITERAL_CSTRING("upgrade"), str, res);
- MOZ_ASSERT(!res.Failed());
- if (!str.EqualsLiteral("websocket")) {
- return false;
- }
-
- headers->GetFirst(NS_LITERAL_CSTRING("connection"), str, res);
- MOZ_ASSERT(!res.Failed());
- if (!ContainsToken(str, NS_LITERAL_CSTRING("Upgrade"))) {
- return false;
- }
-
- headers->GetFirst(NS_LITERAL_CSTRING("sec-websocket-key"), str, res);
- MOZ_ASSERT(!res.Failed());
- nsAutoCString binary;
- if (NS_FAILED(Base64Decode(str, binary)) || binary.Length() != 16) {
- return false;
- }
-
- nsresult rv;
- headers->GetFirst(NS_LITERAL_CSTRING("sec-websocket-version"), str, res);
- MOZ_ASSERT(!res.Failed());
- if (str.ToInteger(&rv) != 13 || NS_FAILED(rv)) {
- return false;
- }
-
- return true;
-}
-
-nsresult
-HttpServer::Connection::ConsumeLine(const char* aBuffer,
- size_t aLength)
-{
- MOZ_ASSERT(mState == eRequestLine ||
- mState == eHeaders);
-
- if (MOZ_LOG_TEST(gHttpServerLog, mozilla::LogLevel::Verbose)) {
- nsCString line(aBuffer, aLength);
- LOG_V("HttpServer::Connection::ConsumeLine(%p) - \"%s\"", this, line.get());
- }
-
- if (mState == eRequestLine) {
- LOG_V("HttpServer::Connection::ConsumeLine(%p) - Parsing request line", this);
- NS_ENSURE_FALSE(mCloseAfterRequest, NS_ERROR_UNEXPECTED);
-
- if (aLength == 0) {
- // Ignore empty lines before the request line
- return NS_OK;
- }
- MOZ_ASSERT(!mPendingReq);
-
- // Process request line
- nsCWhitespaceTokenizer tokens(Substring(aBuffer, aLength));
-
- NS_ENSURE_TRUE(tokens.hasMoreTokens(), NS_ERROR_UNEXPECTED);
- nsDependentCSubstring method = tokens.nextToken();
- NS_ENSURE_TRUE(NS_IsValidHTTPToken(method), NS_ERROR_UNEXPECTED);
- NS_ENSURE_TRUE(tokens.hasMoreTokens(), NS_ERROR_UNEXPECTED);
- nsDependentCSubstring url = tokens.nextToken();
- // Seems like it's also allowed to pass full urls with scheme+host+port.
- // May need to support that.
- NS_ENSURE_TRUE(url.First() == '/', NS_ERROR_UNEXPECTED);
- mPendingReq = new InternalRequest(url, /* aURLFragment */ EmptyCString());
- mPendingReq->SetMethod(method);
- NS_ENSURE_TRUE(tokens.hasMoreTokens(), NS_ERROR_UNEXPECTED);
- nsDependentCSubstring version = tokens.nextToken();
- NS_ENSURE_TRUE(StringBeginsWith(version, NS_LITERAL_CSTRING("HTTP/1.")),
- NS_ERROR_UNEXPECTED);
- nsresult rv;
- // This integer parsing is likely not strict enough.
- nsCString reqVersion;
- reqVersion = Substring(version, MOZ_ARRAY_LENGTH("HTTP/1.") - 1);
- mPendingReqVersion = reqVersion.ToInteger(&rv);
- NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
-
- NS_ENSURE_FALSE(tokens.hasMoreTokens(), NS_ERROR_UNEXPECTED);
-
- LOG_V("HttpServer::Connection::ConsumeLine(%p) - Parsed request line", this);
-
- mState = eHeaders;
-
- return NS_OK;
- }
-
- if (aLength == 0) {
- LOG_V("HttpServer::Connection::ConsumeLine(%p) - Found end of headers", this);
-
- MaybeAddPendingHeader();
-
- ErrorResult res;
- mPendingReq->Headers()->SetGuard(HeadersGuardEnum::Immutable, res);
-
- // Check for WebSocket
- if (IsWebSocketRequest(mPendingReq, mPendingReqVersion)) {
- LOG_V("HttpServer::Connection::ConsumeLine(%p) - Fire OnWebSocket", this);
-
- mState = ePause;
- mPendingWebSocketRequest = mPendingReq.forget();
- mPendingReqVersion = 0;
-
- RefPtr<HttpServerListener> listener = mServer->mListener;
- RefPtr<InternalRequest> request = mPendingWebSocketRequest;
- nsCOMPtr<nsIRunnable> event =
- NS_NewRunnableFunction([listener, request] ()
- {
- listener->OnWebSocket(request);
- });
- NS_DispatchToCurrentThread(event);
-
- return NS_OK;
- }
-
- nsAutoCString header;
- mPendingReq->Headers()->GetFirst(NS_LITERAL_CSTRING("connection"),
- header,
- res);
- MOZ_ASSERT(!res.Failed());
- // 1.0 defaults to closing connections.
- // 1.1 and higher defaults to keep-alive.
- if (ContainsToken(header, NS_LITERAL_CSTRING("close")) ||
- (mPendingReqVersion == 0 &&
- !ContainsToken(header, NS_LITERAL_CSTRING("keep-alive")))) {
- mCloseAfterRequest = true;
- }
-
- mPendingReq->Headers()->GetFirst(NS_LITERAL_CSTRING("content-length"),
- header,
- res);
- MOZ_ASSERT(!res.Failed());
-
- LOG_V("HttpServer::Connection::ConsumeLine(%p) - content-length is \"%s\"",
- this, header.get());
-
- if (!header.IsEmpty()) {
- nsresult rv;
- mRemainingBodySize = header.ToInteger(&rv);
- NS_ENSURE_SUCCESS(rv, rv);
- } else {
- mRemainingBodySize = 0;
- }
-
- if (mRemainingBodySize) {
- LOG_V("HttpServer::Connection::ConsumeLine(%p) - Starting consume body", this);
- mState = eBody;
-
- // We use an unlimited buffer size here to ensure
- // that we get to the next request even if the webpage hangs on
- // to the request indefinitely without consuming the body.
- nsCOMPtr<nsIInputStream> input;
- nsCOMPtr<nsIOutputStream> output;
- nsresult rv = NS_NewPipe(getter_AddRefs(input),
- getter_AddRefs(output),
- 0, // Segment size
- UINT32_MAX, // Unlimited buffer size
- false, // not nonBlockingInput
- true); // nonBlockingOutput
- NS_ENSURE_SUCCESS(rv, rv);
-
- mCurrentRequestBody = do_QueryInterface(output);
- mPendingReq->SetBody(input);
- } else {
- LOG_V("HttpServer::Connection::ConsumeLine(%p) - No body", this);
- mState = eRequestLine;
- }
-
- mPendingRequests.AppendElement(PendingRequest(mPendingReq, nullptr));
-
- LOG_V("HttpServer::Connection::ConsumeLine(%p) - Fire OnRequest", this);
-
- RefPtr<HttpServerListener> listener = mServer->mListener;
- RefPtr<InternalRequest> request = mPendingReq.forget();
- nsCOMPtr<nsIRunnable> event =
- NS_NewRunnableFunction([listener, request] ()
- {
- listener->OnRequest(request);
- });
- NS_DispatchToCurrentThread(event);
-
- mPendingReqVersion = 0;
-
- return NS_OK;
- }
-
- // Parse header line
- if (aBuffer[0] == ' ' || aBuffer[0] == '\t') {
- LOG_V("HttpServer::Connection::ConsumeLine(%p) - Add to header %s",
- this,
- mPendingHeaderName.get());
-
- NS_ENSURE_FALSE(mPendingHeaderName.IsEmpty(),
- NS_ERROR_UNEXPECTED);
-
- // We might need to do whitespace trimming/compression here.
- mPendingHeaderValue.Append(aBuffer, aLength);
- return NS_OK;
- }
-
- MaybeAddPendingHeader();
-
- const char* colon = static_cast<const char*>(memchr(aBuffer, ':', aLength));
- NS_ENSURE_TRUE(colon, NS_ERROR_UNEXPECTED);
-
- ToLowerCase(Substring(aBuffer, colon - aBuffer), mPendingHeaderName);
- mPendingHeaderValue.Assign(colon + 1, aLength - (colon - aBuffer) - 1);
-
- NS_ENSURE_TRUE(NS_IsValidHTTPToken(mPendingHeaderName),
- NS_ERROR_UNEXPECTED);
-
- LOG_V("HttpServer::Connection::ConsumeLine(%p) - Parsed header %s",
- this,
- mPendingHeaderName.get());
-
- return NS_OK;
-}
-
-void
-HttpServer::Connection::MaybeAddPendingHeader()
-{
- if (mPendingHeaderName.IsEmpty()) {
- return;
- }
-
- // We might need to do more whitespace trimming/compression here.
- mPendingHeaderValue.Trim(" \t");
-
- ErrorResult rv;
- mPendingReq->Headers()->Append(mPendingHeaderName, mPendingHeaderValue, rv);
- mPendingHeaderName.Truncate();
-}
-
-bool
-HttpServer::Connection::TryHandleResponse(InternalRequest* aRequest,
- InternalResponse* aResponse)
-{
- bool handledResponse = false;
- for (uint32_t i = 0; i < mPendingRequests.Length(); ++i) {
- PendingRequest& pending = mPendingRequests[i];
- if (pending.first() == aRequest) {
- MOZ_ASSERT(!handledResponse);
- MOZ_ASSERT(!pending.second());
-
- pending.second() = aResponse;
- if (i != 0) {
- return true;
- }
- handledResponse = true;
- }
-
- if (handledResponse && !pending.second()) {
- // Shortcut if we've handled the response, and
- // we don't have more responses to send
- return true;
- }
-
- if (i == 0 && pending.second()) {
- RefPtr<InternalResponse> resp = pending.second().forget();
- mPendingRequests.RemoveElementAt(0);
- QueueResponse(resp);
- --i;
- }
- }
-
- return handledResponse;
-}
-
-already_AddRefed<nsITransportProvider>
-HttpServer::Connection::HandleAcceptWebSocket(const Optional<nsAString>& aProtocol,
- ErrorResult& aRv)
-{
- MOZ_ASSERT(mPendingWebSocketRequest);
-
- RefPtr<InternalResponse> response =
- new InternalResponse(101, NS_LITERAL_CSTRING("Switching Protocols"));
-
- InternalHeaders* headers = response->Headers();
- headers->Set(NS_LITERAL_CSTRING("Upgrade"),
- NS_LITERAL_CSTRING("websocket"),
- aRv);
- headers->Set(NS_LITERAL_CSTRING("Connection"),
- NS_LITERAL_CSTRING("Upgrade"),
- aRv);
- if (aProtocol.WasPassed()) {
- NS_ConvertUTF16toUTF8 protocol(aProtocol.Value());
- nsAutoCString reqProtocols;
- mPendingWebSocketRequest->Headers()->
- GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Protocol"), reqProtocols, aRv);
- if (!ContainsToken(reqProtocols, protocol)) {
- // Should throw a better error here
- aRv.Throw(NS_ERROR_FAILURE);
- return nullptr;
- }
-
- headers->Set(NS_LITERAL_CSTRING("Sec-WebSocket-Protocol"),
- protocol, aRv);
- }
-
- nsAutoCString key, hash;
- mPendingWebSocketRequest->Headers()->
- GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Key"), key, aRv);
- nsresult rv = mozilla::net::CalculateWebSocketHashedSecret(key, hash);
- if (NS_FAILED(rv)) {
- aRv.Throw(rv);
- return nullptr;
- }
- headers->Set(NS_LITERAL_CSTRING("Sec-WebSocket-Accept"), hash, aRv);
-
- nsAutoCString extensions, negotiatedExtensions;
- mPendingWebSocketRequest->Headers()->
- GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Extensions"), extensions, aRv);
- mozilla::net::ProcessServerWebSocketExtensions(extensions,
- negotiatedExtensions);
- if (!negotiatedExtensions.IsEmpty()) {
- headers->Set(NS_LITERAL_CSTRING("Sec-WebSocket-Extensions"),
- negotiatedExtensions, aRv);
- }
-
- RefPtr<TransportProvider> result = new TransportProvider();
- mWebSocketTransportProvider = result;
-
- QueueResponse(response);
-
- return result.forget();
-}
-
-void
-HttpServer::Connection::HandleWebSocketResponse(InternalResponse* aResponse)
-{
- MOZ_ASSERT(mPendingWebSocketRequest);
-
- mState = eRequestLine;
- mPendingWebSocketRequest = nullptr;
- mInput->AsyncWait(this, 0, 0, NS_GetCurrentThread());
-
- QueueResponse(aResponse);
-}
-
-void
-HttpServer::Connection::QueueResponse(InternalResponse* aResponse)
-{
- bool chunked = false;
-
- RefPtr<InternalHeaders> headers = new InternalHeaders(*aResponse->Headers());
- {
- ErrorResult res;
- headers->SetGuard(HeadersGuardEnum::None, res);
- }
- nsCOMPtr<nsIInputStream> body;
- int64_t bodySize;
- aResponse->GetBody(getter_AddRefs(body), &bodySize);
-
- if (body && bodySize >= 0) {
- nsCString sizeStr;
- sizeStr.AppendInt(bodySize);
-
- LOG_V("HttpServer::Connection::QueueResponse(%p) - "
- "Setting content-length to %s",
- this, sizeStr.get());
-
- ErrorResult res;
- headers->Set(NS_LITERAL_CSTRING("content-length"), sizeStr, res);
- } else if (body) {
- // Use chunked transfer encoding
- LOG_V("HttpServer::Connection::QueueResponse(%p) - Chunked transfer-encoding",
- this);
-
- ErrorResult res;
- headers->Set(NS_LITERAL_CSTRING("transfer-encoding"),
- NS_LITERAL_CSTRING("chunked"),
- res);
- headers->Delete(NS_LITERAL_CSTRING("content-length"), res);
- chunked = true;
-
- } else {
- LOG_V("HttpServer::Connection::QueueResponse(%p) - "
- "No body - setting content-length to 0", this);
-
- ErrorResult res;
- headers->Set(NS_LITERAL_CSTRING("content-length"),
- NS_LITERAL_CSTRING("0"), res);
- }
-
- nsCString head(NS_LITERAL_CSTRING("HTTP/1.1 "));
- head.AppendInt(aResponse->GetStatus());
- // XXX is the statustext security checked?
- head.Append(NS_LITERAL_CSTRING(" ") +
- aResponse->GetStatusText() +
- NS_LITERAL_CSTRING("\r\n"));
-
- AutoTArray<InternalHeaders::Entry, 16> entries;
- headers->GetEntries(entries);
-
- for (auto header : entries) {
- head.Append(header.mName +
- NS_LITERAL_CSTRING(": ") +
- header.mValue +
- NS_LITERAL_CSTRING("\r\n"));
- }
-
- head.Append(NS_LITERAL_CSTRING("\r\n"));
-
- mOutputBuffers.AppendElement()->mString = head;
- if (body) {
- OutputBuffer* bodyBuffer = mOutputBuffers.AppendElement();
- bodyBuffer->mStream = body;
- bodyBuffer->mChunked = chunked;
- }
-
- OnOutputStreamReady(mOutput);
-}
-
-namespace {
-
-typedef MozPromise<nsresult, bool, false> StreamCopyPromise;
-
-class StreamCopier final : public nsIOutputStreamCallback
- , public nsIInputStreamCallback
- , public nsIRunnable
-{
-public:
- static RefPtr<StreamCopyPromise>
- Copy(nsIInputStream* aSource, nsIAsyncOutputStream* aSink,
- bool aChunked)
- {
- RefPtr<StreamCopier> copier = new StreamCopier(aSource, aSink, aChunked);
-
- RefPtr<StreamCopyPromise> p = copier->mPromise.Ensure(__func__);
-
- nsresult rv = copier->mTarget->Dispatch(copier, NS_DISPATCH_NORMAL);
- if (NS_FAILED(rv)) {
- copier->mPromise.Resolve(rv, __func__);
- }
-
- return p;
- }
-
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSIINPUTSTREAMCALLBACK
- NS_DECL_NSIOUTPUTSTREAMCALLBACK
- NS_DECL_NSIRUNNABLE
-
-private:
- StreamCopier(nsIInputStream* aSource, nsIAsyncOutputStream* aSink,
- bool aChunked)
- : mSource(aSource)
- , mAsyncSource(do_QueryInterface(aSource))
- , mSink(aSink)
- , mTarget(do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID))
- , mChunkRemaining(0)
- , mChunked(aChunked)
- , mAddedFinalSeparator(false)
- , mFirstChunk(aChunked)
- {
- }
- ~StreamCopier() {}
-
- static nsresult FillOutputBufferHelper(nsIOutputStream* aOutStr,
- void* aClosure,
- char* aBuffer,
- uint32_t aOffset,
- uint32_t aCount,
- uint32_t* aCountRead);
- nsresult FillOutputBuffer(char* aBuffer,
- uint32_t aCount,
- uint32_t* aCountRead);
-
- nsCOMPtr<nsIInputStream> mSource;
- nsCOMPtr<nsIAsyncInputStream> mAsyncSource;
- nsCOMPtr<nsIAsyncOutputStream> mSink;
- MozPromiseHolder<StreamCopyPromise> mPromise;
- nsCOMPtr<nsIEventTarget> mTarget; // XXX we should cache this somewhere
- uint32_t mChunkRemaining;
- nsCString mSeparator;
- bool mChunked;
- bool mAddedFinalSeparator;
- bool mFirstChunk;
-};
-
-NS_IMPL_ISUPPORTS(StreamCopier,
- nsIOutputStreamCallback,
- nsIInputStreamCallback,
- nsIRunnable)
-
-struct WriteState
-{
- StreamCopier* copier;
- nsresult sourceRv;
-};
-
-// This function only exists to enable FillOutputBuffer to be a non-static
-// function where we can use member variables more easily.
-nsresult
-StreamCopier::FillOutputBufferHelper(nsIOutputStream* aOutStr,
- void* aClosure,
- char* aBuffer,
- uint32_t aOffset,
- uint32_t aCount,
- uint32_t* aCountRead)
-{
- WriteState* ws = static_cast<WriteState*>(aClosure);
- ws->sourceRv = ws->copier->FillOutputBuffer(aBuffer, aCount, aCountRead);
- return ws->sourceRv;
-}
-
-nsresult
-CheckForEOF(nsIInputStream* aIn,
- void* aClosure,
- const char* aBuffer,
- uint32_t aToOffset,
- uint32_t aCount,
- uint32_t* aWriteCount)
-{
- *static_cast<bool*>(aClosure) = true;
- *aWriteCount = 0;
- return NS_BINDING_ABORTED;
-}
-
-nsresult
-StreamCopier::FillOutputBuffer(char* aBuffer,
- uint32_t aCount,
- uint32_t* aCountRead)
-{
- nsresult rv = NS_OK;
- while (mChunked && mSeparator.IsEmpty() && !mChunkRemaining &&
- !mAddedFinalSeparator) {
- uint64_t avail;
- rv = mSource->Available(&avail);
- if (rv == NS_BASE_STREAM_CLOSED) {
- avail = 0;
- rv = NS_OK;
- }
- NS_ENSURE_SUCCESS(rv, rv);
-
- mChunkRemaining = avail > UINT32_MAX ? UINT32_MAX :
- static_cast<uint32_t>(avail);
-
- if (!mChunkRemaining) {
- // Either it's an non-blocking stream without any data
- // currently available, or we're at EOF. Sadly there's no way
- // to tell other than to read from the stream.
- bool hadData = false;
- uint32_t numRead;
- rv = mSource->ReadSegments(CheckForEOF, &hadData, 1, &numRead);
- if (rv == NS_BASE_STREAM_CLOSED) {
- avail = 0;
- rv = NS_OK;
- }
- NS_ENSURE_SUCCESS(rv, rv);
- MOZ_ASSERT(numRead == 0);
-
- if (hadData) {
- // The source received data between the call to Available and the
- // call to ReadSegments. Restart with a new call to Available
- continue;
- }
-
- // We're at EOF, write a separator with 0
- mAddedFinalSeparator = true;
- }
-
- if (mFirstChunk) {
- mFirstChunk = false;
- MOZ_ASSERT(mSeparator.IsEmpty());
- } else {
- // For all chunks except the first, add the newline at the end
- // of the previous chunk of data
- mSeparator.AssignLiteral("\r\n");
- }
- mSeparator.AppendInt(mChunkRemaining, 16);
- mSeparator.AppendLiteral("\r\n");
-
- if (mAddedFinalSeparator) {
- mSeparator.AppendLiteral("\r\n");
- }
-
- break;
- }
-
- // If we're doing chunked encoding, we should either have a chunk size,
- // or we should have reached the end of the input stream.
- MOZ_ASSERT_IF(mChunked, mChunkRemaining || mAddedFinalSeparator);
- // We should only have a separator if we're doing chunked encoding
- MOZ_ASSERT_IF(!mSeparator.IsEmpty(), mChunked);
-
- if (!mSeparator.IsEmpty()) {
- *aCountRead = std::min(mSeparator.Length(), aCount);
- memcpy(aBuffer, mSeparator.BeginReading(), *aCountRead);
- mSeparator.Cut(0, *aCountRead);
- rv = NS_OK;
- } else if (mChunked) {
- *aCountRead = 0;
- if (mChunkRemaining) {
- rv = mSource->Read(aBuffer,
- std::min(aCount, mChunkRemaining),
- aCountRead);
- mChunkRemaining -= *aCountRead;
- }
- } else {
- rv = mSource->Read(aBuffer, aCount, aCountRead);
- }
-
- if (NS_SUCCEEDED(rv) && *aCountRead == 0) {
- rv = NS_BASE_STREAM_CLOSED;
- }
-
- return rv;
-}
-
-NS_IMETHODIMP
-StreamCopier::Run()
-{
- nsresult rv;
- while (1) {
- WriteState state = { this, NS_OK };
- uint32_t written;
- rv = mSink->WriteSegments(FillOutputBufferHelper, &state,
- mozilla::net::nsIOService::gDefaultSegmentSize,
- &written);
- MOZ_ASSERT(NS_SUCCEEDED(rv) || NS_SUCCEEDED(state.sourceRv));
- if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
- mSink->AsyncWait(this, 0, 0, mTarget);
- return NS_OK;
- }
- if (NS_FAILED(rv)) {
- mPromise.Resolve(rv, __func__);
- return NS_OK;
- }
-
- if (state.sourceRv == NS_BASE_STREAM_WOULD_BLOCK) {
- MOZ_ASSERT(mAsyncSource);
- mAsyncSource->AsyncWait(this, 0, 0, mTarget);
- mSink->AsyncWait(this, nsIAsyncInputStream::WAIT_CLOSURE_ONLY,
- 0, mTarget);
-
- return NS_OK;
- }
- if (state.sourceRv == NS_BASE_STREAM_CLOSED) {
- // We're done!
- // No longer interested in callbacks about either stream closing
- mSink->AsyncWait(nullptr, 0, 0, nullptr);
- if (mAsyncSource) {
- mAsyncSource->AsyncWait(nullptr, 0, 0, nullptr);
- }
-
- mSource->Close();
- mSource = nullptr;
- mAsyncSource = nullptr;
- mSink = nullptr;
-
- mPromise.Resolve(NS_OK, __func__);
-
- return NS_OK;
- }
-
- if (NS_FAILED(state.sourceRv)) {
- mPromise.Resolve(state.sourceRv, __func__);
- return NS_OK;
- }
- }
-
- MOZ_ASSUME_UNREACHABLE_MARKER();
-}
-
-NS_IMETHODIMP
-StreamCopier::OnInputStreamReady(nsIAsyncInputStream* aStream)
-{
- MOZ_ASSERT(aStream == mAsyncSource ||
- (!mSource && !mAsyncSource && !mSink));
- return mSource ? Run() : NS_OK;
-}
-
-NS_IMETHODIMP
-StreamCopier::OnOutputStreamReady(nsIAsyncOutputStream* aStream)
-{
- MOZ_ASSERT(aStream == mSink ||
- (!mSource && !mAsyncSource && !mSink));
- return mSource ? Run() : NS_OK;
-}
-
-} // namespace
-
-NS_IMETHODIMP
-HttpServer::Connection::OnOutputStreamReady(nsIAsyncOutputStream* aStream)
-{
- MOZ_ASSERT(aStream == mOutput || !mOutput);
- if (!mOutput) {
- return NS_OK;
- }
-
- nsresult rv;
-
- while (!mOutputBuffers.IsEmpty()) {
- if (!mOutputBuffers[0].mStream) {
- nsCString& buffer = mOutputBuffers[0].mString;
- while (!buffer.IsEmpty()) {
- uint32_t written = 0;
- rv = mOutput->Write(buffer.BeginReading(),
- buffer.Length(),
- &written);
-
- buffer.Cut(0, written);
-
- if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
- return mOutput->AsyncWait(this, 0, 0, NS_GetCurrentThread());
- }
-
- if (NS_FAILED(rv)) {
- Close();
- return NS_OK;
- }
- }
- mOutputBuffers.RemoveElementAt(0);
- } else {
- if (mOutputCopy) {
- // we're already copying the stream
- return NS_OK;
- }
-
- mOutputCopy =
- StreamCopier::Copy(mOutputBuffers[0].mStream,
- mOutput,
- mOutputBuffers[0].mChunked);
-
- RefPtr<Connection> self = this;
-
- mOutputCopy->
- Then(AbstractThread::MainThread(),
- __func__,
- [self, this] (nsresult aStatus) {
- MOZ_ASSERT(mOutputBuffers[0].mStream);
- LOG_V("HttpServer::Connection::OnOutputStreamReady(%p) - "
- "Sent body. Status 0x%lx",
- this, aStatus);
-
- mOutputBuffers.RemoveElementAt(0);
- mOutputCopy = nullptr;
- OnOutputStreamReady(mOutput);
- },
- [] (bool) { MOZ_ASSERT_UNREACHABLE("Reject unexpected"); });
- }
- }
-
- if (mPendingRequests.IsEmpty()) {
- if (mCloseAfterRequest) {
- LOG_V("HttpServer::Connection::OnOutputStreamReady(%p) - Closing channel",
- this);
- Close();
- } else if (mWebSocketTransportProvider) {
- mInput->AsyncWait(nullptr, 0, 0, nullptr);
- mOutput->AsyncWait(nullptr, 0, 0, nullptr);
-
- mWebSocketTransportProvider->SetTransport(mTransport, mInput, mOutput);
- mTransport = nullptr;
- mInput = nullptr;
- mOutput = nullptr;
- mWebSocketTransportProvider = nullptr;
- }
- }
-
- return NS_OK;
-}
-
-void
-HttpServer::Connection::Close()
-{
- if (!mTransport) {
- MOZ_ASSERT(!mOutput && !mInput);
- return;
- }
-
- mTransport->Close(NS_BINDING_ABORTED);
- if (mInput) {
- mInput->Close();
- mInput = nullptr;
- }
- if (mOutput) {
- mOutput->Close();
- mOutput = nullptr;
- }
-
- mTransport = nullptr;
-
- mInputBuffer.Truncate();
- mOutputBuffers.Clear();
- mPendingRequests.Clear();
-}
-
-
-} // namespace net
-} // namespace mozilla
diff --git a/dom/flyweb/HttpServer.h b/dom/flyweb/HttpServer.h
deleted file mode 100644
index dab601c24..000000000
--- a/dom/flyweb/HttpServer.h
+++ /dev/null
@@ -1,193 +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/. */
-
-#ifndef mozilla_dom_HttpServer_h
-#define mozilla_dom_HttpServer_h
-
-#include "nsISupportsImpl.h"
-#include "mozilla/DOMEventTargetHelper.h"
-#include "nsITLSServerSocket.h"
-#include "nsIAsyncInputStream.h"
-#include "nsIAsyncOutputStream.h"
-#include "mozilla/Variant.h"
-#include "nsIRequestObserver.h"
-#include "mozilla/MozPromise.h"
-#include "nsITransportProvider.h"
-#include "nsILocalCertService.h"
-
-class nsIX509Cert;
-
-namespace mozilla {
-namespace dom {
-
-extern bool
-ContainsToken(const nsCString& aList, const nsCString& aToken);
-
-class InternalRequest;
-class InternalResponse;
-
-class HttpServerListener
-{
-public:
- // switch to NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING when that lands
- NS_IMETHOD_(MozExternalRefCountType) AddRef(void) = 0;
- NS_IMETHOD_(MozExternalRefCountType) Release(void) = 0;
-
- virtual void OnServerStarted(nsresult aStatus) = 0;
- virtual void OnRequest(InternalRequest* aRequest) = 0;
- virtual void OnWebSocket(InternalRequest* aConnectRequest) = 0;
- virtual void OnServerClose() = 0;
-};
-
-class HttpServer final : public nsIServerSocketListener,
- public nsILocalCertGetCallback
-{
-public:
- HttpServer();
-
- NS_DECL_ISUPPORTS
- NS_DECL_NSISERVERSOCKETLISTENER
- NS_DECL_NSILOCALCERTGETCALLBACK
-
- void Init(int32_t aPort, bool aHttps, HttpServerListener* aListener);
-
- void SendResponse(InternalRequest* aRequest, InternalResponse* aResponse);
- already_AddRefed<nsITransportProvider>
- AcceptWebSocket(InternalRequest* aConnectRequest,
- const Optional<nsAString>& aProtocol,
- ErrorResult& aRv);
- void SendWebSocketResponse(InternalRequest* aConnectRequest,
- InternalResponse* aResponse);
-
- void Close();
-
- void GetCertKey(nsACString& aKey);
-
- int32_t GetPort()
- {
- return mPort;
- }
-
-private:
- ~HttpServer();
-
- nsresult StartServerSocket(nsIX509Cert* aCert);
- void NotifyStarted(nsresult aStatus);
-
- class TransportProvider final : public nsITransportProvider
- {
- public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSITRANSPORTPROVIDER
-
- void SetTransport(nsISocketTransport* aTransport,
- nsIAsyncInputStream* aInput,
- nsIAsyncOutputStream* aOutput);
-
- private:
- virtual ~TransportProvider();
- void MaybeNotify();
-
- nsCOMPtr<nsIHttpUpgradeListener> mListener;
- nsCOMPtr<nsISocketTransport> mTransport;
- nsCOMPtr<nsIAsyncInputStream> mInput;
- nsCOMPtr<nsIAsyncOutputStream> mOutput;
- };
-
- class Connection final : public nsIInputStreamCallback
- , public nsIOutputStreamCallback
- , public nsITLSServerSecurityObserver
- {
- public:
- Connection(nsISocketTransport* aTransport,
- HttpServer* aServer,
- nsresult& rv);
-
- NS_DECL_ISUPPORTS
- NS_DECL_NSIINPUTSTREAMCALLBACK
- NS_DECL_NSIOUTPUTSTREAMCALLBACK
- NS_DECL_NSITLSSERVERSECURITYOBSERVER
-
- bool TryHandleResponse(InternalRequest* aRequest,
- InternalResponse* aResponse);
- already_AddRefed<nsITransportProvider>
- HandleAcceptWebSocket(const Optional<nsAString>& aProtocol,
- ErrorResult& aRv);
- void HandleWebSocketResponse(InternalResponse* aResponse);
- bool HasPendingWebSocketRequest(InternalRequest* aRequest)
- {
- return aRequest == mPendingWebSocketRequest;
- }
-
- void Close();
-
- private:
- ~Connection();
-
- void SetSecurityObserver(bool aListen);
-
- static nsresult ReadSegmentsFunc(nsIInputStream* aIn,
- void* aClosure,
- const char* aBuffer,
- uint32_t aToOffset,
- uint32_t aCount,
- uint32_t* aWriteCount);
- nsresult ConsumeInput(const char*& aBuffer,
- const char* aEnd);
- nsresult ConsumeLine(const char* aBuffer,
- size_t aLength);
- void MaybeAddPendingHeader();
-
- void QueueResponse(InternalResponse* aResponse);
-
- RefPtr<HttpServer> mServer;
- nsCOMPtr<nsISocketTransport> mTransport;
- nsCOMPtr<nsIAsyncInputStream> mInput;
- nsCOMPtr<nsIAsyncOutputStream> mOutput;
-
- enum { eRequestLine, eHeaders, eBody, ePause } mState;
- RefPtr<InternalRequest> mPendingReq;
- uint32_t mPendingReqVersion;
- nsCString mInputBuffer;
- nsCString mPendingHeaderName;
- nsCString mPendingHeaderValue;
- uint32_t mRemainingBodySize;
- nsCOMPtr<nsIAsyncOutputStream> mCurrentRequestBody;
- bool mCloseAfterRequest;
-
- typedef Pair<RefPtr<InternalRequest>,
- RefPtr<InternalResponse>> PendingRequest;
- nsTArray<PendingRequest> mPendingRequests;
- RefPtr<MozPromise<nsresult, bool, false>> mOutputCopy;
-
- RefPtr<InternalRequest> mPendingWebSocketRequest;
- RefPtr<TransportProvider> mWebSocketTransportProvider;
-
- struct OutputBuffer {
- nsCString mString;
- nsCOMPtr<nsIInputStream> mStream;
- bool mChunked;
- };
-
- nsTArray<OutputBuffer> mOutputBuffers;
- };
-
- friend class Connection;
-
- RefPtr<HttpServerListener> mListener;
- nsCOMPtr<nsIServerSocket> mServerSocket;
- nsCOMPtr<nsIX509Cert> mCert;
-
- nsTArray<RefPtr<Connection>> mConnections;
-
- int32_t mPort;
- bool mHttps;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif // mozilla_dom_HttpServer_h
diff --git a/dom/flyweb/PFlyWebPublishedServer.ipdl b/dom/flyweb/PFlyWebPublishedServer.ipdl
deleted file mode 100644
index 4d08a47fc..000000000
--- a/dom/flyweb/PFlyWebPublishedServer.ipdl
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- 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;
-include protocol PSendStream;
-include protocol PFileDescriptorSet;
-include protocol PTransportProvider;
-include FetchTypes;
-include ChannelInfo;
-include PBackgroundSharedTypes;
-
-namespace mozilla {
-namespace dom {
-
-async protocol PFlyWebPublishedServer
-{
- manager PContent;
-
-child:
- async ServerReady(nsresult aStatus);
- async FetchRequest(IPCInternalRequest aRequest, uint64_t aRequestId);
- async WebSocketRequest(IPCInternalRequest aRequest, uint64_t aRequestId,
- PTransportProvider aProvider);
- async ServerClose();
-
-parent:
- async __delete__();
-
- async FetchResponse(IPCInternalResponse aResponse, uint64_t aRequestId);
- async WebSocketResponse(IPCInternalResponse aResponse, uint64_t aRequestId);
- async WebSocketAccept(nsString aProtocol, uint64_t aRequestId);
-};
-
-} // namespace dom
-} // namespace mozilla
diff --git a/dom/flyweb/moz.build b/dom/flyweb/moz.build
deleted file mode 100644
index aa8c034b7..000000000
--- a/dom/flyweb/moz.build
+++ /dev/null
@@ -1,42 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# 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'
-]
-
-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']