mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
53a5e2bb9c
CLOSED TREE Backed out changeset 865e7bc208df (bug 885982) Backed out changeset 9ede577f5ada (bug 885982) Backed out changeset 6ccc86f7429e (bug 1118063) --HG-- rename : dom/network/interfaces/nsITCPServerSocketInternal.idl => dom/network/interfaces/nsIDOMTCPServerSocket.idl
188 lines
5.2 KiB
JavaScript
188 lines
5.2 KiB
JavaScript
/* 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/. */
|
||
|
||
"use strict";
|
||
|
||
const Cc = Components.classes;
|
||
const Ci = Components.interfaces;
|
||
const Cu = Components.utils;
|
||
const Cr = Components.results;
|
||
const CC = Components.Constructor;
|
||
|
||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||
|
||
const ServerSocket = CC(
|
||
'@mozilla.org/network/server-socket;1', 'nsIServerSocket', 'init'),
|
||
TCPSocketInternal = Cc[
|
||
'@mozilla.org/tcp-socket;1'].createInstance(Ci.nsITCPSocketInternal);
|
||
|
||
/*
|
||
* Debug logging function
|
||
*/
|
||
|
||
let debug = true;
|
||
function LOG(msg) {
|
||
if (debug) {
|
||
dump("TCPServerSocket: " + msg + "\n");
|
||
}
|
||
}
|
||
|
||
/*
|
||
* nsIDOMTCPServerSocket object
|
||
*/
|
||
|
||
function TCPServerSocket() {
|
||
this._localPort = 0;
|
||
this._binaryType = null;
|
||
|
||
this._onconnect = null;
|
||
this._onerror = null;
|
||
|
||
this._inChild = false;
|
||
this._neckoTCPServerSocket = null;
|
||
this._serverBridge = null;
|
||
this.useWin = null;
|
||
}
|
||
|
||
// When this API moves to WebIDL and these __exposedProps__ go away, remove
|
||
// this call here and remove the API from XPConnect.
|
||
Cu.skipCOWCallableChecks();
|
||
|
||
TCPServerSocket.prototype = {
|
||
__exposedProps__: {
|
||
localPort: 'r',
|
||
onconnect: 'rw',
|
||
onerror: 'rw'
|
||
},
|
||
get localPort() {
|
||
return this._localPort;
|
||
},
|
||
get onconnect() {
|
||
return this._onconnect;
|
||
},
|
||
set onconnect(f) {
|
||
this._onconnect = f;
|
||
},
|
||
get onerror() {
|
||
return this._onerror;
|
||
},
|
||
set onerror(f) {
|
||
this._onerror = f;
|
||
},
|
||
|
||
_callListenerAcceptCommon: function tss_callListenerAcceptCommon(socket) {
|
||
if (this._onconnect) {
|
||
try {
|
||
this["onconnect"].call(null, socket);
|
||
} catch (e) {
|
||
socket.close();
|
||
}
|
||
}
|
||
else {
|
||
socket.close();
|
||
dump("Received unexpected connection!");
|
||
}
|
||
},
|
||
init: function tss_init(aWindowObj) {
|
||
this.useWin = aWindowObj;
|
||
},
|
||
|
||
/* nsITCPServerSocketInternal method */
|
||
listen: function tss_listen(localPort, options, backlog) {
|
||
this._inChild = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
|
||
.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
|
||
this._binaryType = options.binaryType;
|
||
|
||
if (this._inChild) {
|
||
if (this._serverBridge == null) {
|
||
this._serverBridge = Cc["@mozilla.org/tcp-server-socket-child;1"]
|
||
.createInstance(Ci.nsITCPServerSocketChild);
|
||
this._serverBridge.listen(this, localPort, backlog, options.binaryType);
|
||
}
|
||
else {
|
||
throw new Error("Child TCPServerSocket has already listening. \n");
|
||
}
|
||
}
|
||
else {
|
||
if (this._neckoTCPServerSocket == null) {
|
||
this._neckoTCPServerSocket = new ServerSocket(localPort, false, backlog);
|
||
this._localPort = this._neckoTCPServerSocket.port;
|
||
this._neckoTCPServerSocket.asyncListen(this);
|
||
}
|
||
else {
|
||
throw new Error("Parent TCPServerSocket has already listening. \n");
|
||
}
|
||
}
|
||
},
|
||
|
||
callListenerAccept: function tss_callListenerSocket(socketChild) {
|
||
// this method is called at child process when the socket is accepted at parent process.
|
||
let socket = TCPSocketInternal.createAcceptedChild(socketChild, this._binaryType, this.useWin);
|
||
this._callListenerAcceptCommon(socket);
|
||
},
|
||
|
||
callListenerError: function tss_callListenerError(message, filename, lineNumber, columnNumber) {
|
||
if (this._onerror) {
|
||
var type = "error";
|
||
var error = new Error(message, filename, lineNumber, columnNumber);
|
||
|
||
this["onerror"].call(null, new TCPSocketEvent(type, this, error));
|
||
}
|
||
},
|
||
/* end nsITCPServerSocketInternal method */
|
||
|
||
close: function tss_close() {
|
||
if (this._inChild) {
|
||
this._serverBridge.close();
|
||
return;
|
||
}
|
||
|
||
/* Close ServerSocket */
|
||
if (this._neckoTCPServerSocket) {
|
||
this._neckoTCPServerSocket.close();
|
||
}
|
||
},
|
||
|
||
// nsIServerSocketListener (Triggered by _neckoTCPServerSocket.asyncListen)
|
||
onSocketAccepted: function tss_onSocketAccepted(server, trans) {
|
||
// precondition: this._inChild == false
|
||
try {
|
||
let that = TCPSocketInternal.createAcceptedParent(trans, this._binaryType,
|
||
this.useWin);
|
||
this._callListenerAcceptCommon(that);
|
||
}
|
||
catch(e) {
|
||
trans.close(Cr.NS_BINDING_ABORTED);
|
||
}
|
||
},
|
||
|
||
// nsIServerSocketListener (Triggered by _neckoTCPServerSocket.asyncListen)
|
||
onStopListening: function tss_onStopListening(server, status) {
|
||
if (status != Cr.NS_BINDING_ABORTED) {
|
||
throw new Error("Server socket was closed by unexpected reason.");
|
||
}
|
||
this._neckoTCPServerSocket = null;
|
||
},
|
||
|
||
classID: Components.ID("{73065eae-27dc-11e2-895a-000c29987aa2}"),
|
||
|
||
classInfo: XPCOMUtils.generateCI({
|
||
classID: Components.ID("{73065eae-27dc-11e2-895a-000c29987aa2}"),
|
||
classDescription: "Server TCP Socket",
|
||
interfaces: [
|
||
Ci.nsIDOMTCPServerSocket,
|
||
Ci.nsISupportsWeakReference
|
||
],
|
||
flags: Ci.nsIClassInfo.DOM_OBJECT,
|
||
}),
|
||
|
||
QueryInterface: XPCOMUtils.generateQI([
|
||
Ci.nsIDOMTCPServerSocket,
|
||
Ci.nsITCPServerSocketInternal,
|
||
Ci.nsISupportsWeakReference
|
||
])
|
||
}
|
||
|
||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TCPServerSocket]);
|