Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/third_party/closure/goog/labs/net/webchannel/webchannelbasetransport.js
1865 views
1
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS-IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
/**
16
* @fileoverview Implementation of a WebChannel transport using WebChannelBase.
17
*
18
* When WebChannelBase is used as the underlying transport, the capabilities
19
* of the WebChannel are limited to what's supported by the implementation.
20
* Particularly, multiplexing is not possible, and only strings are
21
* supported as message types.
22
*
23
*/
24
25
goog.provide('goog.labs.net.webChannel.WebChannelBaseTransport');
26
27
goog.require('goog.asserts');
28
goog.require('goog.events.EventTarget');
29
goog.require('goog.json');
30
goog.require('goog.labs.net.webChannel.ChannelRequest');
31
goog.require('goog.labs.net.webChannel.WebChannelBase');
32
goog.require('goog.log');
33
goog.require('goog.net.WebChannel');
34
goog.require('goog.net.WebChannelTransport');
35
goog.require('goog.object');
36
goog.require('goog.string');
37
goog.require('goog.string.path');
38
39
40
41
/**
42
* Implementation of {@link goog.net.WebChannelTransport} with
43
* {@link goog.labs.net.webChannel.WebChannelBase} as the underlying channel
44
* implementation.
45
*
46
* @constructor
47
* @struct
48
* @implements {goog.net.WebChannelTransport}
49
* @final
50
*/
51
goog.labs.net.webChannel.WebChannelBaseTransport = function() {
52
if (!goog.labs.net.webChannel.ChannelRequest.supportsXhrStreaming()) {
53
throw new Error('Environmental error: no available transport.');
54
}
55
};
56
57
58
goog.scope(function() {
59
var WebChannelBaseTransport = goog.labs.net.webChannel.WebChannelBaseTransport;
60
var WebChannelBase = goog.labs.net.webChannel.WebChannelBase;
61
62
63
/**
64
* @override
65
*/
66
WebChannelBaseTransport.prototype.createWebChannel = function(
67
url, opt_options) {
68
return new WebChannelBaseTransport.Channel(url, opt_options);
69
};
70
71
72
73
/**
74
* Implementation of the {@link goog.net.WebChannel} interface.
75
*
76
* @param {string} url The URL path for the new WebChannel instance.
77
* @param {!goog.net.WebChannel.Options=} opt_options Configuration for the
78
* new WebChannel instance.
79
*
80
* @constructor
81
* @implements {goog.net.WebChannel}
82
* @extends {goog.events.EventTarget}
83
* @final
84
*/
85
WebChannelBaseTransport.Channel = function(url, opt_options) {
86
WebChannelBaseTransport.Channel.base(this, 'constructor');
87
88
/**
89
* @private {!WebChannelBase} The underlying channel object.
90
*/
91
this.channel_ = new WebChannelBase(
92
opt_options, goog.net.WebChannelTransport.CLIENT_VERSION);
93
94
/**
95
* @private {string} The URL of the target server end-point.
96
*/
97
this.url_ = url;
98
99
/**
100
* The test URL of the target server end-point. This value defaults to
101
* this.url_ + '/test'.
102
*
103
* @private {string}
104
*/
105
this.testUrl_ = (opt_options && opt_options.testUrl) ?
106
opt_options.testUrl :
107
goog.string.path.join(this.url_, 'test');
108
109
/**
110
* @private {goog.log.Logger} The logger for this class.
111
*/
112
this.logger_ =
113
goog.log.getLogger('goog.labs.net.webChannel.WebChannelBaseTransport');
114
115
/**
116
* @private {Object<string, string>} Extra URL parameters
117
* to be added to each HTTP request.
118
*/
119
this.messageUrlParams_ =
120
(opt_options && opt_options.messageUrlParams) || null;
121
122
var messageHeaders = (opt_options && opt_options.messageHeaders) || null;
123
124
// default is false
125
if (opt_options && opt_options.clientProtocolHeaderRequired) {
126
if (messageHeaders) {
127
goog.object.set(
128
messageHeaders, goog.net.WebChannel.X_CLIENT_PROTOCOL,
129
goog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL);
130
} else {
131
messageHeaders = goog.object.create(
132
goog.net.WebChannel.X_CLIENT_PROTOCOL,
133
goog.net.WebChannel.X_CLIENT_PROTOCOL_WEB_CHANNEL);
134
}
135
}
136
137
this.channel_.setExtraHeaders(messageHeaders);
138
139
var initHeaders = (opt_options && opt_options.initMessageHeaders) || null;
140
this.channel_.setInitHeaders(initHeaders);
141
142
var httpHeadersOverwriteParam =
143
opt_options && opt_options.httpHeadersOverwriteParam;
144
if (httpHeadersOverwriteParam &&
145
!goog.string.isEmptyOrWhitespace(httpHeadersOverwriteParam)) {
146
this.channel_.setHttpHeadersOverwriteParam(httpHeadersOverwriteParam);
147
}
148
149
/**
150
* @private {boolean} Whether to enable CORS.
151
*/
152
this.supportsCrossDomainXhr_ =
153
(opt_options && opt_options.supportsCrossDomainXhr) || false;
154
155
/**
156
* @private {boolean} Whether to send raw Json and bypass v8 wire format.
157
*/
158
this.sendRawJson_ = (opt_options && opt_options.sendRawJson) || false;
159
160
// Note that httpSessionIdParam will be ignored if the same parameter name
161
// has already been specified with messageUrlParams
162
var httpSessionIdParam = opt_options && opt_options.httpSessionIdParam;
163
if (httpSessionIdParam &&
164
!goog.string.isEmptyOrWhitespace(httpSessionIdParam)) {
165
this.channel_.setHttpSessionIdParam(httpSessionIdParam);
166
if (goog.object.containsKey(this.messageUrlParams_, httpSessionIdParam)) {
167
goog.object.remove(this.messageUrlParams_, httpSessionIdParam);
168
goog.log.warning(this.logger_,
169
'Ignore httpSessionIdParam also specified with messageUrlParams: '
170
+ httpSessionIdParam);
171
}
172
}
173
174
/**
175
* The channel handler.
176
*
177
* @private {!WebChannelBaseTransport.Channel.Handler_}
178
*/
179
this.channelHandler_ = new WebChannelBaseTransport.Channel.Handler_(this);
180
};
181
goog.inherits(WebChannelBaseTransport.Channel, goog.events.EventTarget);
182
183
184
/**
185
* @override
186
* @suppress {checkTypes}
187
*/
188
WebChannelBaseTransport.Channel.prototype.addEventListener = function(
189
type, handler, /** boolean= */ opt_capture, opt_handlerScope) {
190
WebChannelBaseTransport.Channel.base(
191
this, 'addEventListener', type, handler, opt_capture, opt_handlerScope);
192
};
193
194
195
/**
196
* @override
197
* @suppress {checkTypes}
198
*/
199
WebChannelBaseTransport.Channel.prototype.removeEventListener = function(
200
type, handler, /** boolean= */ opt_capture, opt_handlerScope) {
201
WebChannelBaseTransport.Channel.base(
202
this, 'removeEventListener', type, handler, opt_capture,
203
opt_handlerScope);
204
};
205
206
207
/**
208
* Test path is always set to "/url/test".
209
*
210
* @override
211
*/
212
WebChannelBaseTransport.Channel.prototype.open = function() {
213
this.channel_.setHandler(this.channelHandler_);
214
if (this.supportsCrossDomainXhr_) {
215
this.channel_.setSupportsCrossDomainXhrs(true);
216
}
217
this.channel_.connect(
218
this.testUrl_, this.url_, (this.messageUrlParams_ || undefined));
219
};
220
221
222
/**
223
* @override
224
*/
225
WebChannelBaseTransport.Channel.prototype.close = function() {
226
this.channel_.disconnect();
227
};
228
229
230
/**
231
* The WebChannelBase only supports object types.
232
*
233
* @param {!goog.net.WebChannel.MessageData} message The message to send.
234
*
235
* @override
236
*/
237
WebChannelBaseTransport.Channel.prototype.send = function(message) {
238
goog.asserts.assert(goog.isObject(message), 'only object type expected');
239
240
if (this.sendRawJson_) {
241
var rawJson = {};
242
rawJson['__data__'] = goog.json.serialize(message);
243
this.channel_.sendMap(rawJson);
244
} else {
245
this.channel_.sendMap(message);
246
}
247
};
248
249
250
/**
251
* @override
252
*/
253
WebChannelBaseTransport.Channel.prototype.disposeInternal = function() {
254
this.channel_.setHandler(null);
255
delete this.channelHandler_;
256
this.channel_.disconnect();
257
delete this.channel_;
258
259
WebChannelBaseTransport.Channel.base(this, 'disposeInternal');
260
};
261
262
263
264
/**
265
* The message event.
266
*
267
* @param {!Array<?>} array The data array from the underlying channel.
268
* @constructor
269
* @extends {goog.net.WebChannel.MessageEvent}
270
* @final
271
*/
272
WebChannelBaseTransport.Channel.MessageEvent = function(array) {
273
WebChannelBaseTransport.Channel.MessageEvent.base(this, 'constructor');
274
275
this.data = array;
276
};
277
goog.inherits(
278
WebChannelBaseTransport.Channel.MessageEvent,
279
goog.net.WebChannel.MessageEvent);
280
281
282
283
/**
284
* The error event.
285
*
286
* @param {WebChannelBase.Error} error The error code.
287
* @constructor
288
* @extends {goog.net.WebChannel.ErrorEvent}
289
* @final
290
*/
291
WebChannelBaseTransport.Channel.ErrorEvent = function(error) {
292
WebChannelBaseTransport.Channel.ErrorEvent.base(this, 'constructor');
293
294
/**
295
* High-level status code.
296
*/
297
this.status = goog.net.WebChannel.ErrorStatus.NETWORK_ERROR;
298
299
/**
300
* @const {WebChannelBase.Error} Internal error code, for debugging use only.
301
*/
302
this.errorCode = error;
303
};
304
goog.inherits(
305
WebChannelBaseTransport.Channel.ErrorEvent, goog.net.WebChannel.ErrorEvent);
306
307
308
309
/**
310
* Implementation of {@link WebChannelBase.Handler} interface.
311
*
312
* @param {!WebChannelBaseTransport.Channel} channel The enclosing WebChannel.
313
*
314
* @constructor
315
* @extends {WebChannelBase.Handler}
316
* @private
317
*/
318
WebChannelBaseTransport.Channel.Handler_ = function(channel) {
319
WebChannelBaseTransport.Channel.Handler_.base(this, 'constructor');
320
321
/**
322
* @type {!WebChannelBaseTransport.Channel}
323
* @private
324
*/
325
this.channel_ = channel;
326
};
327
goog.inherits(WebChannelBaseTransport.Channel.Handler_, WebChannelBase.Handler);
328
329
330
/**
331
* @override
332
*/
333
WebChannelBaseTransport.Channel.Handler_.prototype.channelOpened = function(
334
channel) {
335
goog.log.info(
336
this.channel_.logger_, 'WebChannel opened on ' + this.channel_.url_);
337
this.channel_.dispatchEvent(goog.net.WebChannel.EventType.OPEN);
338
};
339
340
341
/**
342
* @override
343
*/
344
WebChannelBaseTransport.Channel.Handler_.prototype.channelHandleArray =
345
function(channel, array) {
346
goog.asserts.assert(array, 'array expected to be defined');
347
this.channel_.dispatchEvent(
348
new WebChannelBaseTransport.Channel.MessageEvent(array));
349
};
350
351
352
/**
353
* @override
354
*/
355
WebChannelBaseTransport.Channel.Handler_.prototype.channelError = function(
356
channel, error) {
357
goog.log.info(
358
this.channel_.logger_, 'WebChannel aborted on ' + this.channel_.url_ +
359
' due to channel error: ' + error);
360
this.channel_.dispatchEvent(
361
new WebChannelBaseTransport.Channel.ErrorEvent(error));
362
};
363
364
365
/**
366
* @override
367
*/
368
WebChannelBaseTransport.Channel.Handler_.prototype.channelClosed = function(
369
channel, opt_pendingMaps, opt_undeliveredMaps) {
370
goog.log.info(
371
this.channel_.logger_, 'WebChannel closed on ' + this.channel_.url_);
372
this.channel_.dispatchEvent(goog.net.WebChannel.EventType.CLOSE);
373
};
374
375
376
/**
377
* @override
378
*/
379
WebChannelBaseTransport.Channel.prototype.getRuntimeProperties = function() {
380
return new WebChannelBaseTransport.ChannelProperties(this.channel_);
381
};
382
383
384
385
/**
386
* Implementation of the {@link goog.net.WebChannel.RuntimeProperties}.
387
*
388
* @param {!WebChannelBase} channel The underlying channel object.
389
*
390
* @constructor
391
* @implements {goog.net.WebChannel.RuntimeProperties}
392
* @final
393
*/
394
WebChannelBaseTransport.ChannelProperties = function(channel) {
395
/**
396
* The underlying channel object.
397
*
398
* @private {!WebChannelBase}
399
*/
400
this.channel_ = channel;
401
402
};
403
404
405
/**
406
* @override
407
*/
408
WebChannelBaseTransport.ChannelProperties.prototype.getConcurrentRequestLimit =
409
function() {
410
return this.channel_.getForwardChannelRequestPool().getMaxSize();
411
};
412
413
414
/**
415
* @override
416
*/
417
WebChannelBaseTransport.ChannelProperties.prototype.isSpdyEnabled = function() {
418
return this.getConcurrentRequestLimit() > 1;
419
};
420
421
422
/**
423
* @override
424
*/
425
WebChannelBaseTransport.ChannelProperties.prototype.getHttpSessionId =
426
function() {
427
return this.channel_.getHttpSessionId();
428
};
429
430
431
/**
432
* @override
433
*/
434
WebChannelBaseTransport.ChannelProperties.prototype.commit =
435
goog.abstractMethod;
436
437
438
/**
439
* @override
440
*/
441
WebChannelBaseTransport.ChannelProperties.prototype.getNonAckedMessageCount =
442
goog.abstractMethod;
443
444
445
/**
446
* @override
447
*/
448
WebChannelBaseTransport.ChannelProperties.prototype.notifyNonAckedMessageCount =
449
goog.abstractMethod;
450
451
452
/**
453
* @override
454
*/
455
WebChannelBaseTransport.ChannelProperties.prototype.onCommit =
456
goog.abstractMethod;
457
458
459
/**
460
* @override
461
*/
462
WebChannelBaseTransport.ChannelProperties.prototype.ackCommit =
463
goog.abstractMethod;
464
465
466
/** @override */
467
WebChannelBaseTransport.ChannelProperties.prototype.getLastStatusCode =
468
function() {
469
return this.channel_.getLastStatusCode();
470
};
471
}); // goog.scope
472
473