2016-06-02 09:47:00 +03:00
|
|
|
/* -*- 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/. */
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
#include "mozilla/dom/FlyWebPublishedServerIPC.h"
|
2016-06-02 09:47:00 +03:00
|
|
|
#include "mozilla/dom/FlyWebPublishBinding.h"
|
|
|
|
#include "mozilla/dom/FlyWebService.h"
|
2016-11-22 09:15:04 +03:00
|
|
|
#include "mozilla/dom/DocGroup.h"
|
2016-06-02 09:47:00 +03:00
|
|
|
#include "mozilla/dom/Request.h"
|
|
|
|
#include "mozilla/dom/FlyWebServerEvents.h"
|
2016-06-07 12:46:03 +03:00
|
|
|
#include "mozilla/dom/ContentChild.h"
|
2016-06-07 12:46:03 +03:00
|
|
|
#include "mozilla/dom/ContentParent.h"
|
|
|
|
#include "mozilla/dom/InternalResponse.h"
|
2016-06-07 12:46:03 +03:00
|
|
|
#include "mozilla/ipc/IPCStreamUtils.h"
|
2016-06-07 12:46:03 +03:00
|
|
|
#include "mozilla/net/NeckoParent.h"
|
|
|
|
#include "mozilla/net/IPCTransportProvider.h"
|
2016-11-22 09:15:04 +03:00
|
|
|
#include "mozilla/AbstractThread.h"
|
2016-06-07 12:46:03 +03:00
|
|
|
#include "mozilla/ErrorResult.h"
|
2016-06-02 09:47:00 +03:00
|
|
|
#include "mozilla/Preferences.h"
|
2016-08-23 07:09:32 +03:00
|
|
|
#include "mozilla/Unused.h"
|
2016-06-07 12:46:03 +03:00
|
|
|
#include "nsCharSeparatedTokenizer.h"
|
2016-06-02 09:47:00 +03:00
|
|
|
#include "nsGlobalWindow.h"
|
2016-06-07 12:46:03 +03:00
|
|
|
#include "WebSocketChannel.h"
|
2016-06-02 09:47:00 +03:00
|
|
|
|
|
|
|
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__))
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
/******** FlyWebPublishedServer ********/
|
2016-06-02 09:47:00 +03:00
|
|
|
|
|
|
|
FlyWebPublishedServer::FlyWebPublishedServer(nsPIDOMWindowInner* aOwner,
|
|
|
|
const nsAString& aName,
|
2016-06-07 12:46:03 +03:00
|
|
|
const FlyWebPublishOptions& aOptions)
|
2016-06-02 09:47:00 +03:00
|
|
|
: mozilla::DOMEventTargetHelper(aOwner)
|
|
|
|
, mOwnerWindowID(aOwner ? aOwner->WindowID() : 0)
|
|
|
|
, mName(aName)
|
|
|
|
, mUiUrl(aOptions.mUiUrl)
|
|
|
|
, mIsRegistered(true) // Registered by the FlyWebService
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
void
|
|
|
|
FlyWebPublishedServer::LastRelease()
|
2016-06-02 09:47:00 +03:00
|
|
|
{
|
2016-06-07 12:46:03 +03:00
|
|
|
// 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.
|
2016-06-02 09:47:00 +03:00
|
|
|
Close();
|
|
|
|
}
|
|
|
|
|
|
|
|
JSObject*
|
|
|
|
FlyWebPublishedServer::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
|
|
|
{
|
|
|
|
return FlyWebPublishedServerBinding::Wrap(aCx, this, aGivenProto);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FlyWebPublishedServer::Close()
|
|
|
|
{
|
2016-06-07 12:46:03 +03:00
|
|
|
LOG_I("FlyWebPublishedServer::Close(%p)", this);
|
|
|
|
|
2016-06-02 09:47:00 +03:00
|
|
|
// Unregister from server.
|
|
|
|
if (mIsRegistered) {
|
2016-06-07 12:46:03 +03:00
|
|
|
MOZ_ASSERT(FlyWebService::GetExisting());
|
|
|
|
FlyWebService::GetExisting()->UnregisterServer(this);
|
2016-06-02 09:47:00 +03:00
|
|
|
mIsRegistered = false;
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
DispatchTrustedEvent(NS_LITERAL_STRING("close"));
|
2016-06-02 09:47:00 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServer::FireFetchEvent(InternalRequest* aRequest)
|
2016-06-02 09:47:00 +03:00
|
|
|
{
|
|
|
|
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
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServer::FireWebsocketEvent(InternalRequest* aConnectRequest)
|
2016-06-02 09:47:00 +03:00
|
|
|
{
|
|
|
|
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
|
2016-06-07 12:46:03 +03:00
|
|
|
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__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
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()->
|
2016-10-10 20:20:14 +03:00
|
|
|
GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Extensions"), extensions, aRv);
|
2016-06-07 12:46:03 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
/******** FlyWebPublishedServerImpl ********/
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS_INHERITED0(FlyWebPublishedServerImpl, mozilla::DOMEventTargetHelper)
|
|
|
|
|
|
|
|
FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(nsPIDOMWindowInner* aOwner,
|
|
|
|
const nsAString& aName,
|
|
|
|
const FlyWebPublishOptions& aOptions)
|
|
|
|
: FlyWebPublishedServer(aOwner, aName, aOptions)
|
2017-01-25 08:43:30 +03:00
|
|
|
, mHttpServer(
|
|
|
|
new HttpServer(aOwner ?
|
|
|
|
aOwner->GetDocGroup()->AbstractMainThreadFor(TaskCategory::Other) :
|
|
|
|
AbstractThread::MainThread()))
|
2016-06-07 12:46:03 +03:00
|
|
|
{
|
|
|
|
LOG_I("FlyWebPublishedServerImpl::FlyWebPublishedServerImpl(%p)", this);
|
2016-09-08 21:36:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FlyWebPublishedServerImpl::PermissionGranted(bool aGranted)
|
|
|
|
{
|
2016-12-16 06:16:31 +03:00
|
|
|
LOG_I("FlyWebPublishedServerImpl::PermissionGranted(%d)", aGranted);
|
2016-09-08 21:36:53 +03:00
|
|
|
if (!aGranted) {
|
|
|
|
PublishedServerStarted(NS_ERROR_FAILURE);
|
|
|
|
return;
|
|
|
|
}
|
2016-06-07 12:46:03 +03:00
|
|
|
|
|
|
|
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)
|
2016-06-02 09:47:00 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(aRequest);
|
|
|
|
MOZ_ASSERT(aResponse);
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
LOG_I("FlyWebPublishedServerImpl::OnFetchResponse(%p)", this);
|
2016-06-02 09:47:00 +03:00
|
|
|
|
|
|
|
if (mHttpServer) {
|
|
|
|
mHttpServer->SendResponse(aRequest, aResponse);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerImpl::OnWebSocketResponse(InternalRequest* aConnectRequest,
|
|
|
|
InternalResponse* aResponse)
|
2016-06-02 09:47:00 +03:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(aConnectRequest);
|
|
|
|
MOZ_ASSERT(aResponse);
|
|
|
|
|
|
|
|
LOG_I("FlyWebPublishedMDNSServer::OnWebSocketResponse(%p)", this);
|
|
|
|
|
|
|
|
if (mHttpServer) {
|
|
|
|
mHttpServer->SendWebSocketResponse(aConnectRequest, aResponse);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
/******** FlyWebPublishedServerChild ********/
|
|
|
|
|
|
|
|
FlyWebPublishedServerChild::FlyWebPublishedServerChild(nsPIDOMWindowInner* aOwner,
|
|
|
|
const nsAString& aName,
|
|
|
|
const FlyWebPublishOptions& aOptions)
|
|
|
|
: FlyWebPublishedServer(aOwner, aName, aOptions)
|
2016-09-08 21:36:53 +03:00
|
|
|
, mActorExists(false)
|
2016-06-07 12:46:03 +03:00
|
|
|
{
|
2016-06-07 12:46:03 +03:00
|
|
|
LOG_I("FlyWebPublishedServerChild::FlyWebPublishedServerChild(%p)", this);
|
|
|
|
|
|
|
|
// The matching release happens when the actor is destroyed, in
|
|
|
|
// ContentChild::DeallocPFlyWebPublishedServerChild
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
}
|
|
|
|
|
2016-09-08 21:36:53 +03:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerChild::RecvServerReady(const nsresult& aStatus)
|
|
|
|
{
|
|
|
|
LOG_I("FlyWebPublishedServerChild::RecvServerReady(%p)", this);
|
2016-09-08 21:36:53 +03:00
|
|
|
MOZ_ASSERT(mActorExists);
|
2016-06-07 12:46:03 +03:00
|
|
|
|
|
|
|
PublishedServerStarted(aStatus);
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerChild::RecvServerClose()
|
|
|
|
{
|
|
|
|
LOG_I("FlyWebPublishedServerChild::RecvServerClose(%p)", this);
|
2016-09-08 21:36:53 +03:00
|
|
|
MOZ_ASSERT(mActorExists);
|
2016-06-07 12:46:03 +03:00
|
|
|
|
|
|
|
Close();
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerChild::RecvFetchRequest(const IPCInternalRequest& aRequest,
|
|
|
|
const uint64_t& aRequestId)
|
|
|
|
{
|
|
|
|
LOG_I("FlyWebPublishedServerChild::RecvFetchRequest(%p)", this);
|
2016-09-08 21:36:53 +03:00
|
|
|
MOZ_ASSERT(mActorExists);
|
2016-06-07 12:46:03 +03:00
|
|
|
|
|
|
|
RefPtr<InternalRequest> request = new InternalRequest(aRequest);
|
|
|
|
mPendingRequests.Put(request, aRequestId);
|
|
|
|
FireFetchEvent(request);
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerChild::RecvWebSocketRequest(const IPCInternalRequest& aRequest,
|
|
|
|
const uint64_t& aRequestId,
|
|
|
|
PTransportProviderChild* aProvider)
|
|
|
|
{
|
|
|
|
LOG_I("FlyWebPublishedServerChild::RecvWebSocketRequest(%p)", this);
|
2016-09-08 21:36:53 +03:00
|
|
|
MOZ_ASSERT(mActorExists);
|
2016-06-07 12:46:03 +03:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
void
|
|
|
|
FlyWebPublishedServerChild::ActorDestroy(ActorDestroyReason aWhy)
|
|
|
|
{
|
|
|
|
LOG_I("FlyWebPublishedServerChild::ActorDestroy(%p)", this);
|
|
|
|
|
2016-09-08 21:36:53 +03:00
|
|
|
mActorExists = false;
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FlyWebPublishedServerChild::OnFetchResponse(InternalRequest* aRequest,
|
|
|
|
InternalResponse* aResponse)
|
|
|
|
{
|
2016-06-07 12:46:03 +03:00
|
|
|
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
|
|
|
|
|
2016-09-08 21:36:53 +03:00
|
|
|
if (!mActorExists) {
|
2016-06-07 12:46:03 +03:00
|
|
|
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t id = mPendingRequests.Get(aRequest);
|
|
|
|
MOZ_ASSERT(id);
|
|
|
|
mPendingRequests.Remove(aRequest);
|
|
|
|
|
|
|
|
IPCInternalResponse ipcResp;
|
2016-06-07 12:46:03 +03:00
|
|
|
UniquePtr<mozilla::ipc::AutoIPCStream> autoStream;
|
2016-09-21 13:27:26 +03:00
|
|
|
nsIContentChild* cc = static_cast<ContentChild*>(Manager());
|
|
|
|
aResponse->ToIPC(&ipcResp, cc, autoStream);
|
2016-06-07 12:46:03 +03:00
|
|
|
Unused << SendFetchResponse(ipcResp, id);
|
2016-06-07 12:46:03 +03:00
|
|
|
if (autoStream) {
|
|
|
|
autoStream->TakeOptionalValue();
|
|
|
|
}
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
already_AddRefed<nsITransportProvider>
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerChild::OnWebSocketAcceptInternal(InternalRequest* aRequest,
|
2016-06-07 12:46:03 +03:00
|
|
|
const Optional<nsAString>& aProtocol,
|
|
|
|
ErrorResult& aRv)
|
2016-06-07 12:46:03 +03:00
|
|
|
{
|
2016-06-07 12:46:03 +03:00
|
|
|
LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p)", this);
|
|
|
|
|
2016-09-08 21:36:53 +03:00
|
|
|
if (!mActorExists) {
|
2016-06-07 12:46:03 +03:00
|
|
|
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()->
|
2016-10-10 20:20:14 +03:00
|
|
|
GetFirst(NS_LITERAL_CSTRING("Sec-WebSocket-Protocol"), reqProtocols, aRv);
|
2016-06-07 12:46:03 +03:00
|
|
|
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();
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerChild::OnWebSocketResponse(InternalRequest* aRequest,
|
2016-06-07 12:46:03 +03:00
|
|
|
InternalResponse* aResponse)
|
|
|
|
{
|
2016-06-07 12:46:03 +03:00
|
|
|
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
|
|
|
|
|
2016-09-08 21:36:53 +03:00
|
|
|
if (!mActorExists) {
|
2016-06-07 12:46:03 +03:00
|
|
|
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;
|
2016-09-21 13:27:26 +03:00
|
|
|
nsIContentChild* cc = static_cast<ContentChild*>(Manager());
|
|
|
|
aResponse->ToIPC(&ipcResp, cc, autoStream);
|
2016-06-07 12:46:03 +03:00
|
|
|
|
|
|
|
Unused << SendWebSocketResponse(ipcResp, id);
|
|
|
|
if (autoStream) {
|
|
|
|
autoStream->TakeOptionalValue();
|
|
|
|
}
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FlyWebPublishedServerChild::Close()
|
|
|
|
{
|
|
|
|
LOG_I("FlyWebPublishedServerChild::Close(%p)", this);
|
|
|
|
|
|
|
|
FlyWebPublishedServer::Close();
|
|
|
|
|
2016-09-08 21:36:53 +03:00
|
|
|
if (mActorExists) {
|
2016-06-07 12:46:03 +03:00
|
|
|
LOG_I("FlyWebPublishedServerChild::Close - sending __delete__ (%p)", this);
|
|
|
|
|
|
|
|
Send__delete__(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/******** FlyWebPublishedServerParent ********/
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
NS_IMPL_ISUPPORTS(FlyWebPublishedServerParent, nsIDOMEventListener)
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerParent::FlyWebPublishedServerParent(const nsAString& aName,
|
|
|
|
const FlyWebPublishOptions& aOptions)
|
|
|
|
: mActorDestroyed(false)
|
2016-06-07 12:46:03 +03:00
|
|
|
, mNextRequestId(1)
|
2016-06-07 12:46:03 +03:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
mozPromise->Then(
|
2016-11-22 09:15:04 +03:00
|
|
|
// Non DocGroup-version of AbstractThread::MainThread() for the task in parent.
|
2016-06-07 12:46:03 +03:00
|
|
|
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);
|
2016-06-07 12:46:03 +03:00
|
|
|
mPublishedServer->AddEventListener(NS_LITERAL_STRING("websocket"),
|
|
|
|
this, false, false, 2);
|
2016-06-07 12:46:03 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
if (type.EqualsLiteral("websocket")) {
|
|
|
|
RefPtr<InternalRequest> request =
|
|
|
|
static_cast<FlyWebWebSocketEvent*>(aEvent)->Request()->GetInternalRequest();
|
|
|
|
uint64_t id = mNextRequestId++;
|
|
|
|
mPendingRequests.Put(id, request);
|
|
|
|
|
2016-09-09 20:41:32 +03:00
|
|
|
nsTArray<PNeckoParent*> neckoParents;
|
|
|
|
Manager()->ManagedPNeckoParent(neckoParents);
|
|
|
|
if (neckoParents.Length() != 1) {
|
|
|
|
MOZ_CRASH("Expected exactly 1 PNeckoParent instance per PNeckoChild");
|
|
|
|
}
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
RefPtr<TransportProviderParent> provider =
|
|
|
|
static_cast<TransportProviderParent*>(
|
2016-09-09 20:41:32 +03:00
|
|
|
neckoParents[0]->SendPTransportProviderConstructor());
|
2016-06-07 12:46:03 +03:00
|
|
|
|
|
|
|
IPCInternalRequest ipcReq;
|
|
|
|
request->ToIPC(&ipcReq);
|
|
|
|
Unused << SendWebSocketRequest(ipcReq, id, provider);
|
|
|
|
|
|
|
|
mPendingTransportProviders.Put(id, provider.forget());
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
MOZ_CRASH("Unknown event type");
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerParent::RecvFetchResponse(const IPCInternalResponse& aResponse,
|
|
|
|
const uint64_t& aRequestId)
|
|
|
|
{
|
2016-06-07 12:46:03 +03:00
|
|
|
MOZ_ASSERT(!mActorDestroyed);
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
RefPtr<InternalRequest> request;
|
|
|
|
mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
|
2016-06-07 12:46:03 +03:00
|
|
|
if (!request) {
|
|
|
|
static_cast<ContentParent*>(Manager())->KillHard("unknown request id");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<InternalResponse> response = InternalResponse::FromIPC(aResponse);
|
|
|
|
|
|
|
|
mPublishedServer->OnFetchResponse(request, response);
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerParent::RecvWebSocketResponse(const IPCInternalResponse& aResponse,
|
|
|
|
const uint64_t& aRequestId)
|
|
|
|
{
|
2016-06-07 12:46:03 +03:00
|
|
|
MOZ_ASSERT(!mActorDestroyed);
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
mPendingTransportProviders.Remove(aRequestId);
|
|
|
|
|
|
|
|
RefPtr<InternalRequest> request;
|
|
|
|
mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
|
|
|
|
if (!request) {
|
|
|
|
static_cast<ContentParent*>(Manager())->KillHard("unknown websocket request id");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<InternalResponse> response = InternalResponse::FromIPC(aResponse);
|
|
|
|
|
|
|
|
mPublishedServer->OnWebSocketResponse(request, response);
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerParent::RecvWebSocketAccept(const nsString& aProtocol,
|
|
|
|
const uint64_t& aRequestId)
|
|
|
|
{
|
2016-06-07 12:46:03 +03:00
|
|
|
MOZ_ASSERT(!mActorDestroyed);
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
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");
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
Optional<nsAString> protocol;
|
|
|
|
if (!aProtocol.IsVoid()) {
|
|
|
|
protocol = &aProtocol;
|
|
|
|
}
|
|
|
|
|
|
|
|
ErrorResult result;
|
|
|
|
nsCOMPtr<nsITransportProvider> providerServer =
|
|
|
|
mPublishedServer->OnWebSocketAcceptInternal(request, protocol, result);
|
|
|
|
if (result.Failed()) {
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_FAIL_NO_REASON(this);
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
2016-11-23 13:00:42 +03:00
|
|
|
DebugOnly<nsresult> rv = providerServer->SetListener(providerIPC);
|
|
|
|
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
2016-06-07 12:46:03 +03:00
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-07 12:46:03 +03:00
|
|
|
}
|
|
|
|
|
2016-06-07 12:46:03 +03:00
|
|
|
void
|
|
|
|
FlyWebPublishedServerParent::ActorDestroy(ActorDestroyReason aWhy)
|
|
|
|
{
|
|
|
|
LOG_I("FlyWebPublishedServerParent::ActorDestroy(%p)", this);
|
|
|
|
|
|
|
|
mActorDestroyed = true;
|
|
|
|
}
|
|
|
|
|
2016-11-15 06:26:00 +03:00
|
|
|
mozilla::ipc::IPCResult
|
2016-06-07 12:46:03 +03:00
|
|
|
FlyWebPublishedServerParent::Recv__delete__()
|
|
|
|
{
|
|
|
|
LOG_I("FlyWebPublishedServerParent::Recv__delete__(%p)", this);
|
2016-06-07 12:46:03 +03:00
|
|
|
MOZ_ASSERT(!mActorDestroyed);
|
2016-06-07 12:46:03 +03:00
|
|
|
|
|
|
|
if (mPublishedServer) {
|
2016-06-07 12:46:03 +03:00
|
|
|
mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("fetch"),
|
|
|
|
this, false);
|
2016-06-07 12:46:03 +03:00
|
|
|
mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("websocket"),
|
|
|
|
this, false);
|
2016-06-07 12:46:03 +03:00
|
|
|
mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("close"),
|
|
|
|
this, false);
|
2016-06-07 12:46:03 +03:00
|
|
|
mPublishedServer->Close();
|
|
|
|
mPublishedServer = nullptr;
|
2016-06-02 09:47:00 +03:00
|
|
|
}
|
2016-11-15 06:26:00 +03:00
|
|
|
return IPC_OK();
|
2016-06-02 09:47:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
|