Skip to content

Commit add35a6

Browse files
committed
Bug 1263991 part 6: Add e10s support for incoming websocket connections to FlyWebPublishedServer. r=baku,michal
1 parent b799ebc commit add35a6

19 files changed

+534
-26
lines changed

dom/flyweb/FlyWebPublishedServer.cpp

Lines changed: 153 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
#include "mozilla/dom/ContentParent.h"
1414
#include "mozilla/dom/InternalResponse.h"
1515
#include "mozilla/ipc/IPCStreamUtils.h"
16+
#include "mozilla/net/NeckoParent.h"
17+
#include "mozilla/net/IPCTransportProvider.h"
1618
#include "mozilla/ErrorResult.h"
1719
#include "mozilla/Preferences.h"
1820
#include "mozilla/unused.h"
21+
#include "nsCharSeparatedTokenizer.h"
1922
#include "nsGlobalWindow.h"
2023
#include "WebSocketChannel.h"
2124

@@ -295,6 +298,26 @@ FlyWebPublishedServerChild::RecvFetchRequest(const IPCInternalRequest& aRequest,
295298
return true;
296299
}
297300

301+
bool
302+
FlyWebPublishedServerChild::RecvWebSocketRequest(const IPCInternalRequest& aRequest,
303+
const uint64_t& aRequestId,
304+
PTransportProviderChild* aProvider)
305+
{
306+
LOG_I("FlyWebPublishedServerChild::RecvWebSocketRequest(%p)", this);
307+
308+
RefPtr<InternalRequest> request = new InternalRequest(aRequest);
309+
mPendingRequests.Put(request, aRequestId);
310+
311+
// Not addreffing here. The addref was already done when the
312+
// PTransportProvider child constructor original ran.
313+
mPendingTransportProviders.Put(aRequestId,
314+
dont_AddRef(static_cast<TransportProviderChild*>(aProvider)));
315+
316+
FireWebsocketEvent(request);
317+
318+
return true;
319+
}
320+
298321
void
299322
FlyWebPublishedServerChild::ActorDestroy(ActorDestroyReason aWhy)
300323
{
@@ -328,21 +351,70 @@ FlyWebPublishedServerChild::OnFetchResponse(InternalRequest* aRequest,
328351
}
329352

330353
already_AddRefed<nsITransportProvider>
331-
FlyWebPublishedServerChild::OnWebSocketAcceptInternal(InternalRequest* aConnectRequest,
354+
FlyWebPublishedServerChild::OnWebSocketAcceptInternal(InternalRequest* aRequest,
332355
const Optional<nsAString>& aProtocol,
333356
ErrorResult& aRv)
334357
{
335358
LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p)", this);
336359

337-
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
338-
return nullptr;
360+
if (mActorDestroyed) {
361+
LOG_I("FlyWebPublishedServerChild::OnWebSocketAcceptInternal(%p) - No actor!", this);
362+
return nullptr;
363+
}
364+
365+
uint64_t id = mPendingRequests.Get(aRequest);
366+
MOZ_ASSERT(id);
367+
mPendingRequests.Remove(aRequest);
368+
369+
RefPtr<TransportProviderChild> provider;
370+
mPendingTransportProviders.Remove(id, getter_AddRefs(provider));
371+
372+
nsString protocol;
373+
if (aProtocol.WasPassed()) {
374+
protocol = aProtocol.Value();
375+
376+
nsAutoCString reqProtocols;
377+
aRequest->Headers()->
378+
Get(NS_LITERAL_CSTRING("Sec-WebSocket-Protocol"), reqProtocols, aRv);
379+
if (!ContainsToken(reqProtocols, NS_ConvertUTF16toUTF8(protocol))) {
380+
// Should throw a better error here
381+
aRv.Throw(NS_ERROR_FAILURE);
382+
return nullptr;
383+
}
384+
} else {
385+
protocol.SetIsVoid(true);
386+
}
387+
388+
Unused << SendWebSocketAccept(protocol, id);
389+
390+
return provider.forget();
339391
}
340392

341393
void
342-
FlyWebPublishedServerChild::OnWebSocketResponse(InternalRequest* aConnectRequest,
394+
FlyWebPublishedServerChild::OnWebSocketResponse(InternalRequest* aRequest,
343395
InternalResponse* aResponse)
344396
{
345-
// Send ipdl message to parent
397+
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p)", this);
398+
399+
if (mActorDestroyed) {
400+
LOG_I("FlyWebPublishedServerChild::OnFetchResponse(%p) - No actor!", this);
401+
return;
402+
}
403+
404+
uint64_t id = mPendingRequests.Get(aRequest);
405+
MOZ_ASSERT(id);
406+
mPendingRequests.Remove(aRequest);
407+
408+
mPendingTransportProviders.Remove(id);
409+
410+
IPCInternalResponse ipcResp;
411+
UniquePtr<mozilla::ipc::AutoIPCStream> autoStream;
412+
aResponse->ToIPC(&ipcResp, Manager(), autoStream);
413+
414+
Unused << SendWebSocketResponse(ipcResp, id);
415+
if (autoStream) {
416+
autoStream->TakeOptionalValue();
417+
}
346418
}
347419

348420
void
@@ -397,6 +469,8 @@ FlyWebPublishedServerParent::FlyWebPublishedServerParent(const nsAString& aName,
397469

398470
mPublishedServer->AddEventListener(NS_LITERAL_STRING("fetch"),
399471
this, false, false, 2);
472+
mPublishedServer->AddEventListener(NS_LITERAL_STRING("websocket"),
473+
this, false, false, 2);
400474
mPublishedServer->AddEventListener(NS_LITERAL_STRING("close"),
401475
this, false, false, 2);
402476
Unused << SendServerReady(NS_OK);
@@ -435,6 +509,24 @@ FlyWebPublishedServerParent::HandleEvent(nsIDOMEvent* aEvent)
435509
return NS_OK;
436510
}
437511

512+
if (type.EqualsLiteral("websocket")) {
513+
RefPtr<InternalRequest> request =
514+
static_cast<FlyWebWebSocketEvent*>(aEvent)->Request()->GetInternalRequest();
515+
uint64_t id = mNextRequestId++;
516+
mPendingRequests.Put(id, request);
517+
518+
RefPtr<TransportProviderParent> provider =
519+
static_cast<TransportProviderParent*>(
520+
mozilla::net::gNeckoParent->SendPTransportProviderConstructor());
521+
522+
IPCInternalRequest ipcReq;
523+
request->ToIPC(&ipcReq);
524+
Unused << SendWebSocketRequest(ipcReq, id, provider);
525+
526+
mPendingTransportProviders.Put(id, provider.forget());
527+
return NS_OK;
528+
}
529+
438530
MOZ_CRASH("Unknown event type");
439531

440532
return NS_OK;
@@ -444,8 +536,8 @@ bool
444536
FlyWebPublishedServerParent::RecvFetchResponse(const IPCInternalResponse& aResponse,
445537
const uint64_t& aRequestId)
446538
{
447-
RefPtr<InternalRequest> request = mPendingRequests.GetWeak(aRequestId);
448-
mPendingRequests.Remove(aRequestId);
539+
RefPtr<InternalRequest> request;
540+
mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
449541
if (!request) {
450542
static_cast<ContentParent*>(Manager())->KillHard("unknown request id");
451543
return false;
@@ -458,6 +550,58 @@ FlyWebPublishedServerParent::RecvFetchResponse(const IPCInternalResponse& aRespo
458550
return true;
459551
}
460552

553+
bool
554+
FlyWebPublishedServerParent::RecvWebSocketResponse(const IPCInternalResponse& aResponse,
555+
const uint64_t& aRequestId)
556+
{
557+
mPendingTransportProviders.Remove(aRequestId);
558+
559+
RefPtr<InternalRequest> request;
560+
mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
561+
if (!request) {
562+
static_cast<ContentParent*>(Manager())->KillHard("unknown websocket request id");
563+
return false;
564+
}
565+
566+
RefPtr<InternalResponse> response = InternalResponse::FromIPC(aResponse);
567+
568+
mPublishedServer->OnWebSocketResponse(request, response);
569+
570+
return true;
571+
}
572+
573+
bool
574+
FlyWebPublishedServerParent::RecvWebSocketAccept(const nsString& aProtocol,
575+
const uint64_t& aRequestId)
576+
{
577+
RefPtr<TransportProviderParent> providerIPC;
578+
mPendingTransportProviders.Remove(aRequestId, getter_AddRefs(providerIPC));
579+
580+
RefPtr<InternalRequest> request;
581+
mPendingRequests.Remove(aRequestId, getter_AddRefs(request));
582+
583+
if (!request || !providerIPC) {
584+
static_cast<ContentParent*>(Manager())->KillHard("unknown websocket request id");
585+
return false;
586+
}
587+
588+
Optional<nsAString> protocol;
589+
if (!aProtocol.IsVoid()) {
590+
protocol = &aProtocol;
591+
}
592+
593+
ErrorResult result;
594+
nsCOMPtr<nsITransportProvider> providerServer =
595+
mPublishedServer->OnWebSocketAcceptInternal(request, protocol, result);
596+
if (result.Failed()) {
597+
return false;
598+
}
599+
600+
providerServer->SetListener(providerIPC);
601+
602+
return true;
603+
}
604+
461605
void
462606
FlyWebPublishedServerParent::ActorDestroy(ActorDestroyReason aWhy)
463607
{
@@ -474,6 +618,8 @@ FlyWebPublishedServerParent::Recv__delete__()
474618
if (mPublishedServer) {
475619
mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("fetch"),
476620
this, false);
621+
mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("websocket"),
622+
this, false);
477623
mPublishedServer->RemoveEventListener(NS_LITERAL_STRING("close"),
478624
this, false);
479625
mPublishedServer->Close();

dom/flyweb/FlyWebPublishedServerIPC.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
class nsPIDOMWindowInner;
2020

2121
namespace mozilla {
22+
namespace net {
23+
class TransportProviderParent;
24+
class TransportProviderChild;
25+
}
26+
2227
namespace dom {
2328

2429
class FlyWebPublishedServerParent;
@@ -97,6 +102,9 @@ class FlyWebPublishedServerChild final : public FlyWebPublishedServer
97102
virtual bool RecvServerClose() override;
98103
virtual bool RecvFetchRequest(const IPCInternalRequest& aRequest,
99104
const uint64_t& aRequestId) override;
105+
virtual bool RecvWebSocketRequest(const IPCInternalRequest& aRequest,
106+
const uint64_t& aRequestId,
107+
PTransportProviderChild* aProvider) override;
100108

101109
virtual void OnFetchResponse(InternalRequest* aRequest,
102110
InternalResponse* aResponse) override;
@@ -115,6 +123,8 @@ class FlyWebPublishedServerChild final : public FlyWebPublishedServer
115123
~FlyWebPublishedServerChild() {}
116124

117125
nsDataHashtable<nsRefPtrHashKey<InternalRequest>, uint64_t> mPendingRequests;
126+
nsRefPtrHashtable<nsUint64HashKey, TransportProviderChild>
127+
mPendingTransportProviders;
118128
bool mActorDestroyed;
119129
};
120130

@@ -137,12 +147,20 @@ class FlyWebPublishedServerParent final : public PFlyWebPublishedServerParent
137147
virtual bool
138148
RecvFetchResponse(const IPCInternalResponse& aResponse,
139149
const uint64_t& aRequestId) override;
150+
virtual bool
151+
RecvWebSocketResponse(const IPCInternalResponse& aResponse,
152+
const uint64_t& aRequestId) override;
153+
virtual bool
154+
RecvWebSocketAccept(const nsString& aProtocol,
155+
const uint64_t& aRequestId) override;
140156

141157
~FlyWebPublishedServerParent() {}
142158

143159
bool mActorDestroyed;
144160
uint64_t mNextRequestId;
145161
nsRefPtrHashtable<nsUint64HashKey, InternalRequest> mPendingRequests;
162+
nsRefPtrHashtable<nsUint64HashKey, TransportProviderParent>
163+
mPendingTransportProviders;
146164
RefPtr<FlyWebPublishedServerImpl> mPublishedServer;
147165
};
148166

dom/flyweb/HttpServer.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,13 @@ HttpServer::TransportProvider::SetListener(nsIHttpUpgradeListener* aListener)
260260
return NS_OK;
261261
}
262262

263+
NS_IMETHODIMP_(PTransportProviderChild*)
264+
HttpServer::TransportProvider::GetIPCChild()
265+
{
266+
MOZ_CRASH("Don't call this in parent process");
267+
return nullptr;
268+
}
269+
263270
void
264271
HttpServer::TransportProvider::SetTransport(nsISocketTransport* aTransport,
265272
nsIAsyncInputStream* aInput,
@@ -492,7 +499,7 @@ HttpServer::Connection::ConsumeInput(const char*& aBuffer,
492499
return NS_OK;
493500
}
494501

495-
static bool
502+
bool
496503
ContainsToken(const nsCString& aList, const nsCString& aToken)
497504
{
498505
nsCCharSeparatedTokenizer tokens(aList, ',');

dom/flyweb/HttpServer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ class nsIX509Cert;
2323
namespace mozilla {
2424
namespace dom {
2525

26+
extern bool
27+
ContainsToken(const nsCString& aList, const nsCString& aToken);
28+
2629
class InternalRequest;
2730
class InternalResponse;
2831

dom/flyweb/PFlyWebPublishedServer.ipdl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
include protocol PContent;
88
include protocol PSendStream;
99
include protocol PFileDescriptorSet;
10+
include protocol PTransportProvider;
1011
include FetchTypes;
1112
include ChannelInfo;
1213
include PBackgroundSharedTypes;
@@ -21,12 +22,16 @@ async protocol PFlyWebPublishedServer
2122
child:
2223
async ServerReady(nsresult aStatus);
2324
async FetchRequest(IPCInternalRequest aRequest, uint64_t aRequestId);
25+
async WebSocketRequest(IPCInternalRequest aRequest, uint64_t aRequestId,
26+
PTransportProvider aProvider);
2427
async ServerClose();
2528

2629
parent:
2730
async __delete__();
2831

2932
async FetchResponse(IPCInternalResponse aResponse, uint64_t aRequestId);
33+
async WebSocketResponse(IPCInternalResponse aResponse, uint64_t aRequestId);
34+
async WebSocketAccept(nsString aProtocol, uint64_t aRequestId);
3035
};
3136

3237
} // namespace dom

netwerk/ipc/NeckoChild.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "mozilla/net/DNSRequestChild.h"
2020
#include "mozilla/net/RemoteOpenFileChild.h"
2121
#include "mozilla/net/ChannelDiverterChild.h"
22+
#include "mozilla/net/IPCTransportProvider.h"
2223
#include "mozilla/dom/network/TCPSocketChild.h"
2324
#include "mozilla/dom/network/TCPServerSocketChild.h"
2425
#include "mozilla/dom/network/UDPSocketChild.h"
@@ -327,6 +328,22 @@ NeckoChild::DeallocPChannelDiverterChild(PChannelDiverterChild* child)
327328
return true;
328329
}
329330

331+
PTransportProviderChild*
332+
NeckoChild::AllocPTransportProviderChild()
333+
{
334+
// This refcount is transferred to the receiver of the message that
335+
// includes the PTransportProviderChild actor.
336+
RefPtr<TransportProviderChild> res = new TransportProviderChild();
337+
338+
return res.forget().take();
339+
}
340+
341+
bool
342+
NeckoChild::DeallocPTransportProviderChild(PTransportProviderChild* aActor)
343+
{
344+
return true;
345+
}
346+
330347
bool
331348
NeckoChild::RecvAsyncAuthPromptForNestedFrame(const TabId& aNestedFrameId,
332349
const nsCString& aUri,

netwerk/ipc/NeckoChild.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ class NeckoChild :
7575
AllocPChannelDiverterChild(const ChannelDiverterArgs& channel) override;
7676
virtual bool
7777
DeallocPChannelDiverterChild(PChannelDiverterChild* actor) override;
78+
virtual PTransportProviderChild*
79+
AllocPTransportProviderChild() override;
80+
virtual bool
81+
DeallocPTransportProviderChild(PTransportProviderChild* aActor) override;
7882
virtual bool RecvAsyncAuthPromptForNestedFrame(const TabId& aNestedFrameId,
7983
const nsCString& aUri,
8084
const nsString& aRealm,

0 commit comments

Comments
 (0)