[SignalingServer] Optimize dependent modules
[platform/framework/web/wrtjs.git] / device_home / node_modules / engine.io-client / lib / transports / polling.js
1 /**
2  * Module dependencies.
3  */
4
5 var Transport = require('../transport');
6 var parseqs = require('parseqs');
7 var parser = require('engine.io-parser');
8 var inherit = require('component-inherit');
9 var yeast = require('yeast');
10 var debug = require('debug')('engine.io-client:polling');
11
12 /**
13  * Module exports.
14  */
15
16 module.exports = Polling;
17
18 /**
19  * Is XHR2 supported?
20  */
21
22 var hasXHR2 = (function () {
23   var XMLHttpRequest = require('xmlhttprequest-ssl');
24   var xhr = new XMLHttpRequest({ xdomain: false });
25   return null != xhr.responseType;
26 })();
27
28 /**
29  * Polling interface.
30  *
31  * @param {Object} opts
32  * @api private
33  */
34
35 function Polling (opts) {
36   var forceBase64 = (opts && opts.forceBase64);
37   if (!hasXHR2 || forceBase64) {
38     this.supportsBinary = false;
39   }
40   Transport.call(this, opts);
41 }
42
43 /**
44  * Inherits from Transport.
45  */
46
47 inherit(Polling, Transport);
48
49 /**
50  * Transport name.
51  */
52
53 Polling.prototype.name = 'polling';
54
55 /**
56  * Opens the socket (triggers polling). We write a PING message to determine
57  * when the transport is open.
58  *
59  * @api private
60  */
61
62 Polling.prototype.doOpen = function () {
63   this.poll();
64 };
65
66 /**
67  * Pauses polling.
68  *
69  * @param {Function} callback upon buffers are flushed and transport is paused
70  * @api private
71  */
72
73 Polling.prototype.pause = function (onPause) {
74   var self = this;
75
76   this.readyState = 'pausing';
77
78   function pause () {
79     debug('paused');
80     self.readyState = 'paused';
81     onPause();
82   }
83
84   if (this.polling || !this.writable) {
85     var total = 0;
86
87     if (this.polling) {
88       debug('we are currently polling - waiting to pause');
89       total++;
90       this.once('pollComplete', function () {
91         debug('pre-pause polling complete');
92         --total || pause();
93       });
94     }
95
96     if (!this.writable) {
97       debug('we are currently writing - waiting to pause');
98       total++;
99       this.once('drain', function () {
100         debug('pre-pause writing complete');
101         --total || pause();
102       });
103     }
104   } else {
105     pause();
106   }
107 };
108
109 /**
110  * Starts polling cycle.
111  *
112  * @api public
113  */
114
115 Polling.prototype.poll = function () {
116   debug('polling');
117   this.polling = true;
118   this.doPoll();
119   this.emit('poll');
120 };
121
122 /**
123  * Overloads onData to detect payloads.
124  *
125  * @api private
126  */
127
128 Polling.prototype.onData = function (data) {
129   var self = this;
130   debug('polling got data %s', data);
131   var callback = function (packet, index, total) {
132     // if its the first message we consider the transport open
133     if ('opening' === self.readyState && packet.type === 'open') {
134       self.onOpen();
135     }
136
137     // if its a close packet, we close the ongoing requests
138     if ('close' === packet.type) {
139       self.onClose();
140       return false;
141     }
142
143     // otherwise bypass onData and handle the message
144     self.onPacket(packet);
145   };
146
147   // decode payload
148   parser.decodePayload(data, this.socket.binaryType, callback);
149
150   // if an event did not trigger closing
151   if ('closed' !== this.readyState) {
152     // if we got data we're not polling
153     this.polling = false;
154     this.emit('pollComplete');
155
156     if ('open' === this.readyState) {
157       this.poll();
158     } else {
159       debug('ignoring poll - transport state "%s"', this.readyState);
160     }
161   }
162 };
163
164 /**
165  * For polling, send a close packet.
166  *
167  * @api private
168  */
169
170 Polling.prototype.doClose = function () {
171   var self = this;
172
173   function close () {
174     debug('writing close packet');
175     self.write([{ type: 'close' }]);
176   }
177
178   if ('open' === this.readyState) {
179     debug('transport open - closing');
180     close();
181   } else {
182     // in case we're trying to close while
183     // handshaking is in progress (GH-164)
184     debug('transport not open - deferring close');
185     this.once('open', close);
186   }
187 };
188
189 /**
190  * Writes a packets payload.
191  *
192  * @param {Array} data packets
193  * @param {Function} drain callback
194  * @api private
195  */
196
197 Polling.prototype.write = function (packets) {
198   var self = this;
199   this.writable = false;
200   var callbackfn = function () {
201     self.writable = true;
202     self.emit('drain');
203   };
204
205   parser.encodePayload(packets, this.supportsBinary, function (data) {
206     self.doWrite(data, callbackfn);
207   });
208 };
209
210 /**
211  * Generates uri for connection.
212  *
213  * @api private
214  */
215
216 Polling.prototype.uri = function () {
217   var query = this.query || {};
218   var schema = this.secure ? 'https' : 'http';
219   var port = '';
220
221   // cache busting is forced
222   if (false !== this.timestampRequests) {
223     query[this.timestampParam] = yeast();
224   }
225
226   if (!this.supportsBinary && !query.sid) {
227     query.b64 = 1;
228   }
229
230   query = parseqs.encode(query);
231
232   // avoid port if default for schema
233   if (this.port && (('https' === schema && Number(this.port) !== 443) ||
234      ('http' === schema && Number(this.port) !== 80))) {
235     port = ':' + this.port;
236   }
237
238   // prepend ? to query
239   if (query.length) {
240     query = '?' + query;
241   }
242
243   var ipv6 = this.hostname.indexOf(':') !== -1;
244   return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;
245 };