Bug 885982 - Part 2: Convert TCPServerSocket to WebIDL and rewrite in C++. r=asuth,mayhemer,bz

This commit is contained in:
Josh Matthews 2015-03-25 10:36:24 -04:00
parent 6d8316690f
commit eb2db2dd0f
14 changed files with 495 additions and 57 deletions

View File

@ -492,6 +492,10 @@ const kEventConstructors = {
return new TCPSocketEvent(aName, aProps);
},
},
TCPServerSocketEvent: { create: function(aName, aProps) {
return new TCPServerSocketEvent(aName, aProps);
},
},
TimeEvent: { create: function (aName, aProps) {
var e = document.createEvent("timeevent");
e.initTimeEvent(aName, aProps.view, aProps.detail);

View File

@ -0,0 +1,157 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/TCPServerSocketBinding.h"
#include "mozilla/dom/TCPServerSocketEvent.h"
#include "mozilla/dom/TCPSocketBinding.h"
#include "mozilla/dom/Event.h"
#include "mozilla/ErrorResult.h"
#include "TCPServerSocket.h"
#include "TCPSocket.h"
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_CLASS(TCPServerSocket)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(TCPServerSocket,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TCPServerSocket,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mServerSocket)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TCPServerSocket,
DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mServerSocket)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_ADDREF_INHERITED(TCPServerSocket, DOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(TCPServerSocket, DOMEventTargetHelper)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TCPServerSocket)
NS_INTERFACE_MAP_ENTRY(nsIServerSocketListener)
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
TCPServerSocket::TCPServerSocket(nsIGlobalObject* aGlobal, uint16_t aPort,
bool aUseArrayBuffers, uint16_t aBacklog)
: DOMEventTargetHelper(aGlobal)
, mPort(aPort)
, mBacklog(aBacklog)
, mUseArrayBuffers(aUseArrayBuffers)
{
}
TCPServerSocket::~TCPServerSocket()
{
}
nsresult
TCPServerSocket::Init()
{
if (mServerSocket) {
return NS_ERROR_FAILURE;
}
nsresult rv;
mServerSocket = do_CreateInstance("@mozilla.org/network/server-socket;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = mServerSocket->Init(mPort, false, mBacklog);
NS_ENSURE_SUCCESS(rv, rv);
rv = mServerSocket->GetPort(&mPort);
NS_ENSURE_SUCCESS(rv, rv);
rv = mServerSocket->AsyncListen(this);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
already_AddRefed<TCPServerSocket>
TCPServerSocket::Constructor(const GlobalObject& aGlobal,
uint16_t aPort,
const ServerSocketOptions& aOptions,
uint16_t aBacklog,
mozilla::ErrorResult& aRv)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
if (!global) {
aRv = NS_ERROR_FAILURE;
return nullptr;
}
bool useArrayBuffers = aOptions.mBinaryType == TCPSocketBinaryType::Arraybuffer;
nsRefPtr<TCPServerSocket> socket = new TCPServerSocket(global, aPort, useArrayBuffers, aBacklog);
nsresult rv = socket->Init();
if (NS_WARN_IF(NS_FAILED(rv))) {
aRv = NS_ERROR_FAILURE;
return nullptr;
}
return socket.forget();
}
uint16_t
TCPServerSocket::LocalPort()
{
return mPort;
}
void
TCPServerSocket::Close()
{
if (mServerSocket) {
mServerSocket->Close();
}
}
void
TCPServerSocket::FireEvent(const nsAString& aType, TCPSocket* aSocket)
{
AutoJSAPI api;
api.Init(GetOwner());
TCPServerSocketEventInit init;
init.mBubbles = false;
init.mCancelable = false;
init.mSocket = aSocket;
nsRefPtr<TCPServerSocketEvent> event =
TCPServerSocketEvent::Constructor(this, aType, init);
event->SetTrusted(true);
bool dummy;
DispatchEvent(event, &dummy);
}
NS_IMETHODIMP
TCPServerSocket::OnSocketAccepted(nsIServerSocket* aServer, nsISocketTransport* aTransport)
{
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
NS_ENSURE_TRUE(global, NS_ERROR_FAILURE);
nsRefPtr<TCPSocket> socket = TCPSocket::CreateAcceptedSocket(global, aTransport, mUseArrayBuffers);
FireEvent(NS_LITERAL_STRING("connect"), socket);
return NS_OK;
}
NS_IMETHODIMP
TCPServerSocket::OnStopListening(nsIServerSocket* aServer, nsresult aStatus)
{
if (aStatus != NS_BINDING_ABORTED) {
nsRefPtr<Event> event = new Event(GetOwner());
nsresult rv = event->InitEvent(NS_LITERAL_STRING("error"), false, false);
NS_ENSURE_SUCCESS(rv, rv);
event->SetTrusted(true);
bool dummy;
DispatchEvent(event, &dummy);
NS_WARNING("Server socket was closed by unexpected reason.");
return NS_ERROR_FAILURE;
}
mServerSocket = nullptr;
return NS_OK;
}
JSObject*
TCPServerSocket::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return TCPServerSocketBinding::Wrap(aCx, this, aGivenProto);
}

View File

@ -0,0 +1,68 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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_TCPServerSocket_h
#define mozilla_dom_TCPServerSocket_h
#include "mozilla/DOMEventTargetHelper.h"
#include "nsIServerSocket.h"
namespace mozilla {
class ErrorResult;
namespace dom {
struct ServerSocketOptions;
class GlobalObject;
class TCPSocket;
class TCPServerSocket final : public DOMEventTargetHelper
, public nsIServerSocketListener
{
public:
TCPServerSocket(nsIGlobalObject* aGlobal, uint16_t aPort, bool aUseArrayBuffers,
uint16_t aBacklog);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TCPServerSocket, DOMEventTargetHelper)
NS_DECL_NSISERVERSOCKETLISTENER
nsPIDOMWindow* GetParentObject() const
{
return GetOwner();
}
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
uint16_t LocalPort();
void Close();
static already_AddRefed<TCPServerSocket>
Constructor(const GlobalObject& aGlobal,
uint16_t aPort,
const ServerSocketOptions& aOptions,
uint16_t aBacklog,
mozilla::ErrorResult& aRv);
IMPL_EVENT_HANDLER(connect);
IMPL_EVENT_HANDLER(error);
private:
~TCPServerSocket();
nsresult Init();
// Dispatch a TCPServerSocketEvent event of a given type at this object.
void FireEvent(const nsAString& aType, TCPSocket* aSocket);
// The server socket associated with this object.
nsCOMPtr<nsIServerSocket> mServerSocket;
int32_t mPort;
uint16_t mBacklog;
// True if any accepted sockets should use array buffers for received messages.
bool mUseArrayBuffers;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TCPServerSocket_h

View File

@ -5,6 +5,7 @@
#include "mozilla/ErrorResult.h"
#include "TCPSocket.h"
#include "TCPServerSocket.h"
#include "mozilla/dom/DOMError.h"
#include "mozilla/dom/TCPSocketBinding.h"
#include "mozilla/dom/TCPSocketErrorEvent.h"
@ -73,6 +74,20 @@ LegacyMozTCPSocket::Open(const nsAString& aHost,
return TCPSocket::Constructor(globalObj, aHost, aPort, aOptions, aRv);
}
already_AddRefed<TCPServerSocket>
LegacyMozTCPSocket::Listen(uint16_t aPort,
const ServerSocketOptions& aOptions,
uint16_t aBacklog,
mozilla::ErrorResult& aRv)
{
AutoJSAPI api;
if (NS_WARN_IF(!api.Init(mGlobal))) {
return nullptr;
}
GlobalObject globalObj(api.cx(), mGlobal->GetGlobalJSObject());
return TCPServerSocket::Constructor(globalObj, aPort, aOptions, aBacklog, aRv);
}
bool
LegacyMozTCPSocket::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto,
@ -158,6 +173,60 @@ TCPSocket::~TCPSocket()
{
}
nsresult
TCPSocket::CreateStream()
{
nsresult rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(mSocketInputStream));
NS_ENSURE_SUCCESS(rv, rv);
rv = mTransport->OpenOutputStream(nsITransport::OPEN_UNBUFFERED, 0, 0, getter_AddRefs(mSocketOutputStream));
NS_ENSURE_SUCCESS(rv, rv);
// If the other side is not listening, we will
// get an onInputStreamReady callback where available
// raises to indicate the connection was refused.
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(mSocketInputStream);
NS_ENSURE_TRUE(asyncStream, NS_ERROR_NOT_AVAILABLE);
nsCOMPtr<nsIThread> mainThread;
NS_GetMainThread(getter_AddRefs(mainThread));
rv = asyncStream->AsyncWait(this, nsIAsyncInputStream::WAIT_CLOSURE_ONLY, 0, mainThread);
NS_ENSURE_SUCCESS(rv, rv);
if (mUseArrayBuffers) {
mInputStreamBinary = do_CreateInstance("@mozilla.org/binaryinputstream;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = mInputStreamBinary->SetInputStream(mSocketInputStream);
NS_ENSURE_SUCCESS(rv, rv);
} else {
mInputStreamScriptable = do_CreateInstance("@mozilla.org/scriptableinputstream;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = mInputStreamScriptable->Init(mSocketInputStream);
NS_ENSURE_SUCCESS(rv, rv);
}
mMultiplexStream = do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
mMultiplexStreamCopier = do_CreateInstance("@mozilla.org/network/async-stream-copier;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISocketTransportService> sts =
do_GetService("@mozilla.org/network/socket-transport-service;1");
nsCOMPtr<nsIEventTarget> target = do_QueryInterface(sts);
rv = mMultiplexStreamCopier->Init(mMultiplexStream,
mSocketOutputStream,
target,
true, /* source buffered */
false, /* sink buffered */
BUFFER_SIZE,
false, /* close source */
false); /* close sink */
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
TCPSocket::Init()
{
@ -186,47 +255,29 @@ TCPSocket::Init()
mTransport->SetEventSink(this, mainThread);
rv = mTransport->OpenInputStream(0, 0, 0, getter_AddRefs(mSocketInputStream));
NS_ENSURE_SUCCESS(rv, rv);
rv = mTransport->OpenOutputStream(nsITransport::OPEN_UNBUFFERED, 0, 0, getter_AddRefs(mSocketOutputStream));
rv = CreateStream();
NS_ENSURE_SUCCESS(rv, rv);
// If the other side is not listening, we will
// get an onInputStreamReady callback where available
// raises to indicate the connection was refused.
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(mSocketInputStream);
NS_ENSURE_TRUE(asyncStream, NS_ERROR_NOT_AVAILABLE);
rv = asyncStream->AsyncWait(this, nsIAsyncInputStream::WAIT_CLOSURE_ONLY, 0, mainThread);
return NS_OK;
}
nsresult
TCPSocket::InitWithTransport(nsISocketTransport* aTransport)
{
mTransport = aTransport;
nsresult rv = CreateStream();
NS_ENSURE_SUCCESS(rv, rv);
if (mUseArrayBuffers) {
mInputStreamBinary = do_CreateInstance("@mozilla.org/binaryinputstream;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = mInputStreamBinary->SetInputStream(mSocketInputStream);
NS_ENSURE_SUCCESS(rv, rv);
} else {
mInputStreamScriptable = do_CreateInstance("@mozilla.org/scriptableinputstream;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = mInputStreamScriptable->Init(mSocketInputStream);
NS_ENSURE_SUCCESS(rv, rv);
}
mMultiplexStream = do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1", &rv);
mReadyState = TCPReadyState::Open;
rv = CreateInputStreamPump();
NS_ENSURE_SUCCESS(rv, rv);
mMultiplexStreamCopier = do_CreateInstance("@mozilla.org/network/async-stream-copier;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIEventTarget> target = do_QueryInterface(sts);
rv = mMultiplexStreamCopier->Init(mMultiplexStream,
mSocketOutputStream,
target,
true, /* source buffered */
false, /* sink buffered */
BUFFER_SIZE,
false, /* close source */
false); /* close sink */
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString host;
mTransport->GetHost(host);
mHost = NS_ConvertUTF8toUTF16(host);
int32_t port;
mTransport->GetPort(&port);
mPort = port;
#ifdef MOZ_WIDGET_GONK
nsCOMPtr<nsINetworkManager> networkManager = do_GetService("@mozilla.org/network/manager;1");
@ -704,6 +755,17 @@ TCPSocket::BinaryType()
}
}
already_AddRefed<TCPSocket>
TCPSocket::CreateAcceptedSocket(nsIGlobalObject* aGlobal,
nsISocketTransport* aTransport,
bool aUseArrayBuffers)
{
nsRefPtr<TCPSocket> socket = new TCPSocket(aGlobal, EmptyString(), 0, false, aUseArrayBuffers);
nsresult rv = socket->InitWithTransport(aTransport);
NS_ENSURE_SUCCESS(rv, nullptr);
return socket.forget();
}
already_AddRefed<TCPSocket>
TCPSocket::Constructor(const GlobalObject& aGlobal,
const nsAString& aHost,
@ -724,17 +786,9 @@ TCPSocket::Constructor(const GlobalObject& aGlobal,
return socket.forget();
}
NS_IMETHODIMP
TCPSocket::OnTransportStatus(nsITransport* aTransport, nsresult aStatus,
int64_t aProgress, int64_t aProgressMax)
nsresult
TCPSocket::CreateInputStreamPump()
{
if (static_cast<uint32_t>(aStatus) != nsISocketTransport::STATUS_CONNECTED_TO) {
return NS_OK;
}
mReadyState = TCPReadyState::Open;
FireEvent(NS_LITERAL_STRING("open"));
nsresult rv;
mInputStreamPump = do_CreateInstance("@mozilla.org/network/input-stream-pump;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
@ -752,6 +806,22 @@ TCPSocket::OnTransportStatus(nsITransport* aTransport, nsresult aStatus,
return NS_OK;
}
NS_IMETHODIMP
TCPSocket::OnTransportStatus(nsITransport* aTransport, nsresult aStatus,
int64_t aProgress, int64_t aProgressMax)
{
if (static_cast<uint32_t>(aStatus) != nsISocketTransport::STATUS_CONNECTED_TO) {
return NS_OK;
}
mReadyState = TCPReadyState::Open;
FireEvent(NS_LITERAL_STRING("open"));
nsresult rv = CreateInputStreamPump();
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
TCPSocket::OnInputStreamReady(nsIAsyncInputStream* aStream)
{

View File

@ -30,6 +30,8 @@ class ErrorResult;
namespace dom {
class DOMError;
struct ServerSocketOptions;
class TCPServerSocket;
class USVStringOrArrayBuffer;
// This interface is only used for legacy navigator.mozTCPSocket API compatibility.
@ -41,6 +43,12 @@ public:
explicit LegacyMozTCPSocket(nsPIDOMWindow* aWindow);
already_AddRefed<TCPServerSocket>
Listen(uint16_t aPort,
const ServerSocketOptions& aOptions,
uint16_t aBacklog,
ErrorResult& aRv);
already_AddRefed<TCPSocket>
Open(const nsAString& aHost,
uint16_t aPort,
@ -106,6 +114,11 @@ public:
const SocketOptions& aOptions,
ErrorResult& aRv);
// Create a TCPSocket object from an existing low-level socket connection.
// Used by the TCPServerSocket implementation when a new connection is accepted.
static already_AddRefed<TCPSocket>
CreateAcceptedSocket(nsIGlobalObject* aGlobal, nsISocketTransport* aTransport, bool aUseArrayBuffers);
static bool SocketEnabled();
IMPL_EVENT_HANDLER(open);
@ -122,6 +135,12 @@ public:
private:
~TCPSocket();
// Initialize this socket from an existing low-level connection.
nsresult InitWithTransport(nsISocketTransport* aTransport);
// Initialize the input/output streams for this socket object.
nsresult CreateStream();
// Initialize the asynchronous read operation from this socket's input stream.
nsresult CreateInputStreamPump();
// Send the contents of the provided input stream, which is assumed to be the given length
// for reporting and buffering purposes.
bool Send(nsIInputStream* aStream, uint32_t aByteLength);

View File

@ -17,6 +17,7 @@ if CONFIG['MOZ_B2G_RIL']:
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
EXPORTS.mozilla.dom += [
'TCPServerSocket.h',
'TCPSocket.h',
'UDPSocket.h',
]
@ -35,6 +36,7 @@ EXPORTS.mozilla.dom.network += [
UNIFIED_SOURCES += [
'Connection.cpp',
'TCPServerSocket.cpp',
'TCPServerSocketChild.cpp',
'TCPServerSocketParent.cpp',
'TCPSocket.cpp',

View File

@ -13,6 +13,7 @@ skip-if = toolkit == "gonk"
skip-if = toolkit == "gonk"
[test_tcpsocket_enabled_with_perm.html]
skip-if = toolkit == "gonk" || e10s
[test_tcpsocket_legacy.html]
[test_networkstats_alarms.html]
skip-if = toolkit != "gonk"
[test_networkstats_basics.html]

View File

@ -127,7 +127,7 @@ function waitForConnection(listeningServer) {
// Because of the event model of sockets, we can't use the
// listenForEventsOnSocket mechanism; we need to hook up listeners during
// the connect event.
listeningServer.onconnect = function(socket) {
listeningServer.onconnect = function(event) {
// Clobber the listener to get upset if it receives any more connections
// after this.
listeningServer.onconnect = function() {
@ -135,8 +135,8 @@ function waitForConnection(listeningServer) {
};
ok(true, 'Listening server accepted socket');
resolve({
socket: socket,
queue: listenForEventsOnSocket(socket, 'server')
socket: event.socket,
queue: listenForEventsOnSocket(event.socket, 'server')
});
};
});
@ -171,11 +171,10 @@ function* test_basics() {
// test was using.
let serverPort = 8085;
let mozTCPSocket = navigator.mozTCPSocket;
// - Start up a listening socket.
let listeningServer = mozTCPSocket.listen(serverPort,
{ binaryType: 'arraybuffer' },
SERVER_BACKLOG);
let listeningServer = new TCPServerSocket(serverPort,
{ binaryType: 'arraybuffer' },
SERVER_BACKLOG);
let connectedPromise = waitForConnection(listeningServer);

View File

@ -0,0 +1,56 @@
<!DOCTYPE HTML>
<html>
<!--
Test of legacy navigator interface for opening TCPSocket/TCPServerSocket.
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 885982</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1084245">Mozilla Bug 1084245</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
</pre>
<script>
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{ set: [ ['dom.mozTCPSocket.enabled', true] ] },
setPerms);
function setPerms() {
SpecialPowers.pushPermissions(
[ { type: 'tcp-socket', allow: true, context: document } ],
runTest);
}
function runTest() {
// See bug 903830; in e10s mode we never get to find out the localPort if we
// let it pick a free port by choosing 0. This is the same port the xpcshell
// test was using.
var serverPort = 8085;
var listeningServer = navigator.mozTCPSocket.listen(serverPort,
{ binaryType: 'arraybuffer' },
-1);
listeningServer.onconnect = function(ev) {
ok(true, "got server connect");
ev.socket.close()
}
var clientSocket = navigator.mozTCPSocket.open('127.0.0.1', serverPort,
{ binaryType: 'arraybuffer' });
clientSocket.onopen = function() { ok(true, "got client open"); }
clientSocket.onclose = function() {
ok(true, "got client close");
SimpleTest.finish();
}
}
</script>
</body>
</html>

View File

@ -436,13 +436,10 @@ partial interface Navigator {
readonly attribute Presentation? presentation;
};
/*
// Commented out due to the continued presence of nsIDOMTCPSocket and its navigator
// properties that interfere with tests.
partial interface Navigator {
partial interface Navigator {
[NewObject, Pref="dom.mozTCPSocket.enabled", CheckAnyPermissions="tcp-socket"]
readonly attribute LegacyMozTCPSocket mozTCPSocket;
};*/
};
#ifdef MOZ_EME
partial interface Navigator {

View File

@ -0,0 +1,43 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
/**
* TCPServerSocket
*
* An interface to a server socket that can accept incoming connections for gaia apps.
*/
dictionary ServerSocketOptions {
TCPSocketBinaryType binaryType = "string";
};
[Constructor(unsigned short port, optional ServerSocketOptions options, optional unsigned short backlog = 0),
Pref="dom.mozTCPSocket.enabled",
CheckAnyPermissions="tcp-socket",
Exposed=Window]
interface TCPServerSocket : EventTarget {
/**
* The port of this server socket object.
*/
readonly attribute unsigned short localPort;
/**
* The "connect" event is dispatched when a client connection is accepted.
* The event object will be a TCPServerSocketEvent containing a TCPSocket
* instance, which is used for communication between client and server.
*/
attribute EventHandler onconnect;
/**
* The "error" event will be dispatched when a listening server socket is
* unexpectedly disconnected.
*/
attribute EventHandler onerror;
/**
* Close the server socket.
*/
void close();
};

View File

@ -0,0 +1,16 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
[Constructor(DOMString type, optional TCPServerSocketEventInit eventInitDict),
Pref="dom.mozTCPSocket.enabled",
CheckAnyPermissions="tcp-socket",
Exposed=Window]
interface TCPServerSocketEvent : Event {
readonly attribute TCPSocket socket;
};
dictionary TCPServerSocketEventInit : EventInit {
TCPSocket? socket = null;
};

View File

@ -34,6 +34,9 @@ interface LegacyMozTCPSocket {
*/
[Throws]
TCPSocket open(DOMString host, unsigned short port, optional SocketOptions options);
[Throws]
TCPServerSocket listen(unsigned short port, optional ServerSocketOptions options, optional unsigned short backlog = 0);
};
[Constructor(DOMString host, unsigned short port, optional SocketOptions options),

View File

@ -524,6 +524,8 @@ WEBIDL_FILES = [
'SVGZoomAndPan.webidl',
'SVGZoomEvent.webidl',
'SystemUpdate.webidl',
'TCPServerSocket.webidl',
'TCPServerSocketEvent.webidl',
'TCPSocket.webidl',
'TCPSocketErrorEvent.webidl',
'TCPSocketEvent.webidl',
@ -799,6 +801,7 @@ GENERATED_EVENTS_WEBIDL_FILES = [
'StyleRuleChangeEvent.webidl',
'StyleSheetApplicableStateChangeEvent.webidl',
'StyleSheetChangeEvent.webidl',
'TCPServerSocketEvent.webidl',
'TCPSocketErrorEvent.webidl',
'TCPSocketEvent.webidl',
'TrackEvent.webidl',