|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 const Cc = Components.classes; |
|
8 const Ci = Components.interfaces; |
|
9 const Cu = Components.utils; |
|
10 |
|
11 Cu.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
12 |
|
13 function TCPSocketParentIntermediary() { |
|
14 } |
|
15 |
|
16 TCPSocketParentIntermediary.prototype = { |
|
17 _setCallbacks: function(aParentSide, socket) { |
|
18 aParentSide.initJS(this); |
|
19 this._socket = socket; |
|
20 |
|
21 // Create handlers for every possible callback that attempt to trigger |
|
22 // corresponding callbacks on the child object. |
|
23 // ondrain event is not forwarded, since the decision of firing ondrain |
|
24 // is made in child. |
|
25 ["open", "data", "error", "close"].forEach( |
|
26 function(p) { |
|
27 socket["on" + p] = function(data) { |
|
28 aParentSide.sendEvent(p, data.data, socket.readyState, |
|
29 socket.bufferedAmount); |
|
30 }; |
|
31 } |
|
32 ); |
|
33 }, |
|
34 |
|
35 _onUpdateBufferedAmountHandler: function(aParentSide, aBufferedAmount, aTrackingNumber) { |
|
36 aParentSide.sendUpdateBufferedAmount(aBufferedAmount, aTrackingNumber); |
|
37 }, |
|
38 |
|
39 open: function(aParentSide, aHost, aPort, aUseSSL, aBinaryType, aAppId) { |
|
40 let baseSocket = Cc["@mozilla.org/tcp-socket;1"].createInstance(Ci.nsIDOMTCPSocket); |
|
41 let socket = baseSocket.open(aHost, aPort, {useSecureTransport: aUseSSL, binaryType: aBinaryType}); |
|
42 if (!socket) |
|
43 return null; |
|
44 |
|
45 let socketInternal = socket.QueryInterface(Ci.nsITCPSocketInternal); |
|
46 if (socketInternal) { |
|
47 socketInternal.setAppId(aAppId); |
|
48 } |
|
49 |
|
50 // Handle parent's request to update buffered amount. |
|
51 socketInternal.setOnUpdateBufferedAmountHandler( |
|
52 this._onUpdateBufferedAmountHandler.bind(this, aParentSide)); |
|
53 |
|
54 // Handlers are set to the JS-implemented socket object on the parent side. |
|
55 this._setCallbacks(aParentSide, socket); |
|
56 return socket; |
|
57 }, |
|
58 |
|
59 listen: function(aTCPServerSocketParent, aLocalPort, aBacklog, aBinaryType) { |
|
60 let baseSocket = Cc["@mozilla.org/tcp-socket;1"].createInstance(Ci.nsIDOMTCPSocket); |
|
61 let serverSocket = baseSocket.listen(aLocalPort, { binaryType: aBinaryType }, aBacklog); |
|
62 if (!serverSocket) |
|
63 return null; |
|
64 |
|
65 let localPort = serverSocket.localPort; |
|
66 |
|
67 serverSocket["onconnect"] = function(socket) { |
|
68 var socketParent = Cc["@mozilla.org/tcp-socket-parent;1"] |
|
69 .createInstance(Ci.nsITCPSocketParent); |
|
70 var intermediary = new TCPSocketParentIntermediary(); |
|
71 // Handlers are set to the JS-implemented socket object on the parent side, |
|
72 // so that the socket parent object can communicate data |
|
73 // with the corresponding socket child object through IPC. |
|
74 intermediary._setCallbacks(socketParent, socket); |
|
75 // The members in the socket parent object are set with arguments, |
|
76 // so that the socket parent object can communicate data |
|
77 // with the JS socket object on the parent side via the intermediary object. |
|
78 socketParent.setSocketAndIntermediary(socket, intermediary); |
|
79 aTCPServerSocketParent.sendCallbackAccept(socketParent); |
|
80 }; |
|
81 |
|
82 serverSocket["onerror"] = function(data) { |
|
83 var error = data.data; |
|
84 |
|
85 aTCPServerSocketParent.sendCallbackError(error.message, error.filename, |
|
86 error.lineNumber, error.columnNumber); |
|
87 }; |
|
88 |
|
89 return serverSocket; |
|
90 }, |
|
91 |
|
92 onRecvSendString: function(aData, aTrackingNumber) { |
|
93 let socketInternal = this._socket.QueryInterface(Ci.nsITCPSocketInternal); |
|
94 return socketInternal.onRecvSendFromChild(aData, 0, 0, aTrackingNumber); |
|
95 }, |
|
96 |
|
97 onRecvSendArrayBuffer: function(aData, aTrackingNumber) { |
|
98 let socketInternal = this._socket.QueryInterface(Ci.nsITCPSocketInternal); |
|
99 return socketInternal.onRecvSendFromChild(aData, 0, aData.byteLength, |
|
100 aTrackingNumber); |
|
101 }, |
|
102 |
|
103 classID: Components.ID("{afa42841-a6cb-4a91-912f-93099f6a3d18}"), |
|
104 QueryInterface: XPCOMUtils.generateQI([ |
|
105 Ci.nsITCPSocketIntermediary |
|
106 ]) |
|
107 }; |
|
108 |
|
109 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([TCPSocketParentIntermediary]); |