[Pkg-javascript-commits] [sockjs-client] 99/350: Add xhr for node. Refactor jsonp.
tonnerre at ancient-solutions.com
tonnerre at ancient-solutions.com
Fri Aug 5 01:03:47 UTC 2016
This is an automated email from the git hooks/post-receive script.
tonnerre-guest pushed a commit to branch upstream
in repository sockjs-client.
commit 94c88742c13311f79995583fce08e01404b8bdef
Author: Bryce Kahle <bkahle at gmail.com>
Date: Thu Oct 9 16:50:36 2014 -0400
Add xhr for node. Refactor jsonp.
---
lib/entry.js | 2 +
lib/transport/{sender => browser}/abstract-xhr.js | 8 +
lib/transport/driver/xhr.js | 57 +++++
lib/transport/iframe-xhr-polling.js | 3 +-
lib/transport/jsonp-polling.js | 258 ++--------------------
lib/transport/lib/ajax-based.js | 6 +
lib/transport/receiver/jsonp.js | 153 +++++++++++++
lib/transport/sender/jsonp.js | 67 ++++++
lib/transport/sender/xhr-cors.js | 8 +-
lib/transport/sender/xhr-fake.js | 1 +
lib/transport/sender/xhr-local.js | 8 +-
lib/transport/xdr-polling.js | 2 +-
lib/transport/xhr-polling.js | 8 +-
lib/transport/xhr-streaming.js | 11 +-
package.json | 9 +-
15 files changed, 340 insertions(+), 261 deletions(-)
diff --git a/lib/entry.js b/lib/entry.js
index 1591a96..9e188c8 100644
--- a/lib/entry.js
+++ b/lib/entry.js
@@ -17,6 +17,8 @@ var browserTransports = [
var nodeTransports = [
require('./transport/websocket')
+, require('./transport/xhr-streaming')
+, require('./transport/xhr-polling')
];
var transports = typeof window !== 'undefined' ? browserTransports : nodeTransports;
diff --git a/lib/transport/sender/abstract-xhr.js b/lib/transport/browser/abstract-xhr.js
similarity index 93%
rename from lib/transport/sender/abstract-xhr.js
rename to lib/transport/browser/abstract-xhr.js
index a20b8d3..066b01e 100644
--- a/lib/transport/sender/abstract-xhr.js
+++ b/lib/transport/browser/abstract-xhr.js
@@ -110,4 +110,12 @@ AbstractXHRObject.prototype.close = function() {
this._cleanup(true);
};
+AbstractXHRObject.enabled = !!global.XMLHttpRequest;
+
+var cors = false;
+try { cors = 'withCredentials' in new global.XMLHttpRequest(); }
+catch (ignored) {}
+
+AbstractXHRObject.supportsCORS = cors;
+
module.exports = AbstractXHRObject;
diff --git a/lib/transport/driver/xhr.js b/lib/transport/driver/xhr.js
new file mode 100644
index 0000000..87b4580
--- /dev/null
+++ b/lib/transport/driver/xhr.js
@@ -0,0 +1,57 @@
+'use strict';
+
+var EventEmitter = require('events').EventEmitter
+ , util = require('util')
+ , http = require('http')
+ , u = require('url')
+ ;
+
+function XhrDriver(method, url, payload, opts) {
+ var self = this;
+ EventEmitter.call(this);
+
+ var parsedUrl = u.parse(url);
+ var options = {
+ method: method
+ , hostname: parsedUrl.hostname
+ , port: parsedUrl.port
+ , path: parsedUrl.path
+ , headers: opts && opts.headers
+ , agent: false
+ };
+
+ this.req = http.request(options, function (res) {
+ res.setEncoding('utf8');
+ var responseText;
+
+ res.on('data', function (chunk) {
+ responseText += chunk;
+ });
+ res.on('end', function () {
+ self.emit('finish', res.statusCode, responseText);
+ self.req = null;
+ });
+ });
+
+ this.req.on('error', function (e) {
+ self.emit('finish', 0, e.message);
+ });
+
+ this.req.write(payload);
+ this.req.end();
+}
+
+util.inherits(XhrDriver, EventEmitter);
+
+XhrDriver.prototype.close = function() {
+ this.removeAllListeners();
+ if (this.req) {
+ this.req.abort();
+ this.req = null;
+ }
+};
+
+XhrDriver.enabled = true;
+XhrDriver.supportsCORS = true;
+
+module.exports = XhrDriver;
\ No newline at end of file
diff --git a/lib/transport/iframe-xhr-polling.js b/lib/transport/iframe-xhr-polling.js
index 43fa15a..231460c 100644
--- a/lib/transport/iframe-xhr-polling.js
+++ b/lib/transport/iframe-xhr-polling.js
@@ -2,6 +2,7 @@
var util = require('util')
, IframeTransport = require('./lib/iframe')
+ , XHRLocalObject = require('./sender/xhr-local')
;
function XhrPollingIframeTransport(transUrl, baseUrl) {
@@ -11,7 +12,7 @@ function XhrPollingIframeTransport(transUrl, baseUrl) {
util.inherits(XhrPollingIframeTransport, IframeTransport);
XhrPollingIframeTransport.enabled = function () {
- return global.XMLHttpRequest && IframeTransport.enabled();
+ return XHRLocalObject.enabled && IframeTransport.enabled();
};
XhrPollingIframeTransport.transportName = 'iframe-xhr-polling';
diff --git a/lib/transport/jsonp-polling.js b/lib/transport/jsonp-polling.js
index 492e872..b713dcf 100644
--- a/lib/transport/jsonp-polling.js
+++ b/lib/transport/jsonp-polling.js
@@ -2,265 +2,37 @@
// The simplest and most robust transport, using the well-know cross
// domain hack - JSONP. This transport is quite inefficient - one
-// mssage could use up to one http request. But at least it works almost
+// message could use up to one http request. But at least it works almost
// everywhere.
// Known limitations:
// o you will get a spinning cursor
// o for Konqueror a dumb timer is needed to detect errors
var util = require('util')
- , utils = require('../utils')
, BufferedSender = require('./lib/buffered-sender')
- , TransportMessageEvent = require('./lib/trans-message-event')
+ , Polling = require('./lib/polling')
+ , JsonpReceiver = require('./receiver/jsonp')
+ , jsonpSender = require('./sender/jsonp')
;
-// Abstract away code that handles global namespace pollution.
-var jsonPReceiverWrapper = function(url, constructReceiver, userCallback) {
- var id = 'a' + utils.randomString(6);
- var urlId = url + '?c=' + encodeURIComponent(utils.WPrefix + '.' + id);
-
- // Unfortunately it is not possible to abort loading of the
- // script. We need to keep track of frake close frames.
- var aborting = 0;
-
- // Callback will be called exactly once.
- var callback = function(frame) {
- switch(aborting) {
- case 0:
- // Normal behaviour - delete hook _and_ emit message.
- delete window[utils.WPrefix][id];
- userCallback(frame);
- break;
- case 1:
- // Fake close frame - emit but don't delete hook.
- userCallback(frame);
- aborting = 2;
- break;
- case 2:
- // Got frame after connection was closed, delete hook, don't emit.
- delete window[utils.WPrefix][id];
- break;
- }
- };
-
- var closeScript = constructReceiver(urlId, callback);
- window[utils.WPrefix][id] = closeScript;
- var stop = function() {
- if (window[utils.WPrefix][id]) {
- aborting = 1;
- var err = new Error('JSONP user aborted read');
- err.code = 1000;
- window[utils.WPrefix][id](err);
- }
- };
- return stop;
-};
-
-function jsonPGenericSender(url, payload, callback) {
- var form = window._sendForm;
- var area = window._sendArea;
-
- if (!form) {
- form = window._sendForm = document.createElement('form');
- area = window._sendArea = document.createElement('textarea');
- area.name = 'd';
- form.style.display = 'none';
- form.style.position = 'absolute';
- form.method = 'POST';
- form.enctype = 'application/x-www-form-urlencoded';
- form.acceptCharset = 'UTF-8';
- form.appendChild(area);
- document.body.appendChild(form);
- }
- var id = 'a' + utils.randomString(8);
- form.target = id;
- form.action = url + '/jsonp_send?i=' + id;
-
- var iframe;
- try {
- // ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
- iframe = document.createElement('<iframe name="' + id + '">');
- } catch(x) {
- iframe = document.createElement('iframe');
- iframe.name = id;
- }
- iframe.id = id;
- form.appendChild(iframe);
- iframe.style.display = 'none';
-
- try {
- area.value = payload;
- } catch(e) {
- utils.log('Your browser is seriously broken. Go home! ' + e.message);
- }
- form.submit();
-
- var completed = function() {
- if (!iframe.onerror) {
- return;
- }
- iframe.onreadystatechange = iframe.onerror = iframe.onload = null;
- // Opera mini doesn't like if we GC iframe
- // immediately, thus this timeout.
- setTimeout(function() {
- iframe.parentNode.removeChild(iframe);
- iframe = null;
- }, 500);
- area.value = '';
- // It is not possible to detect if the iframe succeeded or
- // failed to submit our form.
- callback();
- };
- iframe.onerror = iframe.onload = completed;
- iframe.onreadystatechange = function() {
- if (iframe.readyState === 'complete') {
- completed();
- }
- };
- return completed;
-}
-
-// Parts derived from Socket.io:
-// https://github.com/LearnBoost/socket.io/blob/0.6.17/lib/socket.io/transports/jsonp-polling.js
-// and jQuery-JSONP:
-// https://code.google.com/p/jquery-jsonp/source/browse/trunk/core/jquery.jsonp.js
-function jsonPGenericReceiver(url, callback) {
- var tref;
- var script = global.document.createElement('script');
- var script2; // Opera synchronous load trick.
- var closeScript = function(err) {
- if (script2) {
- script2.parentNode.removeChild(script2);
- script2 = null;
- }
- if (script) {
- clearTimeout(tref);
- // Unfortunately, you can't really abort script loading of
- // the script.
- script.parentNode.removeChild(script);
- script.onreadystatechange = script.onerror =
- script.onload = script.onclick = null;
- script = null;
- callback(err);
- callback = null;
- }
- };
-
- // IE9 fires 'error' event after orsc or before, in random order.
- var loadedOkay = false;
- var errorTimer = null;
-
- script.id = 'a' + utils.randomString(8);
- script.src = url;
- script.type = 'text/javascript';
- script.charset = 'UTF-8';
- script.onerror = function() {
- if (!errorTimer) {
- // Delay firing closeScript.
- errorTimer = setTimeout(function() {
- if (!loadedOkay) {
- closeScript(new Error('JSONP script loaded abnormally (onerror)'));
- }
- }, 1000);
- }
- };
- script.onload = function() {
- closeScript(new Error('JSONP script loaded abnormally (onload)'));
- };
-
- script.onreadystatechange = function() {
- if (/loaded|closed/.test(script.readyState)) {
- if (script && script.htmlFor && script.onclick) {
- loadedOkay = true;
- try {
- // In IE, actually execute the script.
- script.onclick();
- } catch (x) {}
- }
- if (script) {
- closeScript(new Error('JSONP script loaded abnormally (onreadystatechange)'));
- }
- }
- };
- // IE: event/htmlFor/onclick trick.
- // One can't rely on proper order for onreadystatechange. In order to
- // make sure, set a 'htmlFor' and 'event' properties, so that
- // script code will be installed as 'onclick' handler for the
- // script object. Later, onreadystatechange, manually execute this
- // code. FF and Chrome doesn't work with 'event' and 'htmlFor'
- // set. For reference see:
- // http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html
- // Also, read on that about script ordering:
- // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
- if (typeof script.async === 'undefined' && document.attachEvent) {
- // According to mozilla docs, in recent browsers script.async defaults
- // to 'true', so we may use it to detect a good browser:
- // https://developer.mozilla.org/en/HTML/Element/script
- if (!/opera/i.test(navigator.userAgent)) {
- // Naively assume we're in IE
- try {
- script.htmlFor = script.id;
- script.event = 'onclick';
- } catch (x) {}
- script.async = true;
- } else {
- // Opera, second sync script hack
- script2 = document.createElement('script');
- script2.text = "try{var a = document.getElementById('" + script.id + "'); if(a)a.onerror();}catch(x){};";
- script.async = script2.async = false;
- }
- }
- if (typeof script.async !== 'undefined') {
- script.async = true;
- }
-
- // Fallback mostly for Konqueror - stupid timer, 35 seconds shall be plenty.
- tref = setTimeout(function() {
- closeScript(new Error('JSONP script loaded abnormally (timeout)'));
- }, 35000);
-
- var head = document.getElementsByTagName('head')[0];
- head.insertBefore(script, head.firstChild);
- if (script2) {
- head.insertBefore(script2, head.firstChild);
- }
- return closeScript;
-}
-
function JsonPTransport(transUrl) {
- utils.polluteGlobalNamespace();
- this.transUrl = transUrl;
- BufferedSender.call(this, transUrl, jsonPGenericSender);
- this._scheduleReceiver();
+ var self = this;
+ BufferedSender.call(this, transUrl, jsonpSender);
+
+ this.poll = new Polling(JsonpReceiver, this.transUrl + '/jsonp');
+ this.poll.onmessage = this.poll.onclose = function (e) {
+ self.dispatchEvent(e);
+ };
}
util.inherits(JsonPTransport, BufferedSender);
-JsonPTransport.prototype._scheduleReceiver = function() {
- var self = this;
- var callback = function(data) {
- self._receiveStop = null;
- if (data) {
- // no data - heartbeat;
- if (!self._isClosing) {
- self.dispatchEvent(new TransportMessageEvent(data));
- }
- }
- // The message can be a close message, and change is_closing state.
- if (!self._isClosing) {
- self._scheduleReceiver();
- }
- };
- this._receiveStop = jsonPReceiverWrapper(this.transUrl + '/jsonp',
- jsonPGenericReceiver, callback);
-};
-
JsonPTransport.prototype.close = function() {
- this._isClosing = true;
- if (this._receiveStop) {
- this._receiveStop();
+ if (this.poll) {
+ this.poll.abort();
+ this.poll.onmessage = this.poll.onclose = null;
+ this.poll = null;
}
- this._receiveStop = null;
this.stop();
};
diff --git a/lib/transport/lib/ajax-based.js b/lib/transport/lib/ajax-based.js
index 9257328..f70190f 100644
--- a/lib/transport/lib/ajax-based.js
+++ b/lib/transport/lib/ajax-based.js
@@ -25,8 +25,13 @@ function createAjaxSender(AjaxObject) {
}
function AjaxBasedTransport(transUrl, urlSuffix, Receiver, AjaxObject) {
+ var self = this;
BufferedSender.call(this, transUrl, createAjaxSender(AjaxObject));
+
this.poll = new Polling(Receiver, transUrl + urlSuffix, AjaxObject);
+ this.poll.onmessage = this.poll.onclose = function (e) {
+ self.dispatchEvent(e);
+ };
}
util.inherits(AjaxBasedTransport, BufferedSender);
@@ -34,6 +39,7 @@ util.inherits(AjaxBasedTransport, BufferedSender);
AjaxBasedTransport.prototype.close = function() {
if (this.poll) {
this.poll.abort();
+ this.poll.onmessage = this.poll.onclose = null;
this.poll = null;
}
this.stop();
diff --git a/lib/transport/receiver/jsonp.js b/lib/transport/receiver/jsonp.js
new file mode 100644
index 0000000..83a9f61
--- /dev/null
+++ b/lib/transport/receiver/jsonp.js
@@ -0,0 +1,153 @@
+'use strict';
+
+var utils = require('../../utils')
+ , util = require('util')
+ , SimpleEvent = require('../../simpleevent')
+ , EventTarget = require('../../polyfills/eventtarget')
+ ;
+
+function JsonpReceiver(url) {
+ EventTarget.call(this);
+
+ utils.polluteGlobalNamespace();
+
+ this.id = 'a' + utils.randomString(6);
+ var urlId = url + '?c=' + encodeURIComponent(utils.WPrefix + '.' + this.id);
+
+ window[utils.WPrefix][this.id] = this.callback.bind(this);
+ this.createScript(urlId);
+}
+
+util.inherits(JsonpReceiver, EventTarget);
+
+JsonpReceiver.prototype.callback = function (data) {
+ this.deleteScript();
+ delete window[utils.WPrefix][this.id];
+
+ if (this.aborting) {
+ return;
+ }
+
+ if (data) {
+ this.dispatchEvent(new SimpleEvent('message', { data: data }));
+ }
+ this.dispatchEvent(new SimpleEvent('close', { reason: 'network' }));
+};
+
+JsonpReceiver.prototype.abort = function () {
+ if (window[utils.WPrefix][this.id]) {
+ var err = new Error('JSONP user aborted read');
+ err.code = 1000;
+ this._abort(err);
+ }
+};
+
+module.exports = JsonpReceiver;
+
+JsonpReceiver.prototype._abort = function (err) {
+ this.deleteScript();
+ this.aborting = true;
+ this.dispatchEvent(new SimpleEvent('close', { reason: 'permanent' }));
+};
+
+JsonpReceiver.prototype.deleteScript = function () {
+ if (this.script2) {
+ this.script2.parentNode.removeChild(this.script2);
+ this.script2 = null;
+ }
+ if (this.script) {
+ var script = this.script;
+ clearTimeout(this.tref);
+ // Unfortunately, you can't really abort script loading of
+ // the script.
+ script.parentNode.removeChild(script);
+ script.onreadystatechange = script.onerror =
+ script.onload = script.onclick = null;
+ this.script = null;
+ }
+};
+
+JsonpReceiver.prototype.createScript = function (url) {
+ var self = this;
+ var script = this.script = global.document.createElement('script');
+ var script2; // Opera synchronous load trick.
+
+ // IE9 fires 'error' event after orsc or before, in random order.
+ var loadedOkay = false;
+ var errorTimer = null;
+
+ script.id = 'a' + utils.randomString(8);
+ script.src = url;
+ script.type = 'text/javascript';
+ script.charset = 'UTF-8';
+ script.onerror = function() {
+ if (!errorTimer) {
+ // Delay firing closeScript.
+ errorTimer = setTimeout(function() {
+ if (!loadedOkay) {
+ self._abort(new Error('JSONP script loaded abnormally (onerror)'));
+ }
+ }, 1000);
+ }
+ };
+ script.onload = function() {
+ self._abort(new Error('JSONP script loaded abnormally (onload)'));
+ };
+
+ script.onreadystatechange = function() {
+ if (/loaded|closed/.test(script.readyState)) {
+ if (script && script.htmlFor && script.onclick) {
+ loadedOkay = true;
+ try {
+ // In IE, actually execute the script.
+ script.onclick();
+ } catch (x) {}
+ }
+ if (script) {
+ self._abort(new Error('JSONP script loaded abnormally (onreadystatechange)'));
+ }
+ }
+ };
+ // IE: event/htmlFor/onclick trick.
+ // One can't rely on proper order for onreadystatechange. In order to
+ // make sure, set a 'htmlFor' and 'event' properties, so that
+ // script code will be installed as 'onclick' handler for the
+ // script object. Later, onreadystatechange, manually execute this
+ // code. FF and Chrome doesn't work with 'event' and 'htmlFor'
+ // set. For reference see:
+ // http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html
+ // Also, read on that about script ordering:
+ // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
+ if (typeof script.async === 'undefined' && document.attachEvent) {
+ // According to mozilla docs, in recent browsers script.async defaults
+ // to 'true', so we may use it to detect a good browser:
+ // https://developer.mozilla.org/en/HTML/Element/script
+ if (!/opera/i.test(navigator.userAgent)) {
+ // Naively assume we're in IE
+ try {
+ script.htmlFor = script.id;
+ script.event = 'onclick';
+ } catch (x) {}
+ script.async = true;
+ } else {
+ // Opera, second sync script hack
+ script2 = this.script2 = document.createElement('script');
+ script2.text = "try{var a = document.getElementById('" + script.id + "'); if(a)a.onerror();}catch(x){};";
+ script.async = script2.async = false;
+ }
+ }
+ if (typeof script.async !== 'undefined') {
+ script.async = true;
+ }
+
+ // Fallback mostly for Konqueror - stupid timer, 35 seconds shall be plenty.
+ this.tref = setTimeout(function() {
+ self._abort(new Error('JSONP script loaded abnormally (timeout)'));
+ }, 35000);
+
+ var head = document.getElementsByTagName('head')[0];
+ head.insertBefore(script, head.firstChild);
+ if (script2) {
+ head.insertBefore(script2, head.firstChild);
+ }
+};
diff --git a/lib/transport/sender/jsonp.js b/lib/transport/sender/jsonp.js
new file mode 100644
index 0000000..75a5bce
--- /dev/null
+++ b/lib/transport/sender/jsonp.js
@@ -0,0 +1,67 @@
+'use strict';
+
+var utils = require('../../utils');
+
+module.exports = function (url, payload, callback) {
+ var form = window._sendForm;
+ var area = window._sendArea;
+
+ if (!form) {
+ form = window._sendForm = document.createElement('form');
+ area = window._sendArea = document.createElement('textarea');
+ area.name = 'd';
+ form.style.display = 'none';
+ form.style.position = 'absolute';
+ form.method = 'POST';
+ form.enctype = 'application/x-www-form-urlencoded';
+ form.acceptCharset = 'UTF-8';
+ form.appendChild(area);
+ document.body.appendChild(form);
+ }
+ var id = 'a' + utils.randomString(8);
+ form.target = id;
+ form.action = url + '/jsonp_send?i=' + id;
+
+ var iframe;
+ try {
+ // ie6 dynamic iframes with target="" support (thanks Chris Lambacher)
+ iframe = document.createElement('<iframe name="' + id + '">');
+ } catch(x) {
+ iframe = document.createElement('iframe');
+ iframe.name = id;
+ }
+ iframe.id = id;
+ form.appendChild(iframe);
+ iframe.style.display = 'none';
+
+ try {
+ area.value = payload;
+ } catch(e) {
+ utils.log('Your browser is seriously broken. Go home! ' + e.message);
+ }
+ form.submit();
+
+ var completed = function() {
+ if (!iframe.onerror) {
+ return;
+ }
+ iframe.onreadystatechange = iframe.onerror = iframe.onload = null;
+ // Opera mini doesn't like if we GC iframe
+ // immediately, thus this timeout.
+ setTimeout(function() {
+ iframe.parentNode.removeChild(iframe);
+ iframe = null;
+ }, 500);
+ area.value = '';
+ // It is not possible to detect if the iframe succeeded or
+ // failed to submit our form.
+ callback();
+ };
+ iframe.onerror = iframe.onload = completed;
+ iframe.onreadystatechange = function() {
+ if (iframe.readyState === 'complete') {
+ completed();
+ }
+ };
+ return completed;
+};
diff --git a/lib/transport/sender/xhr-cors.js b/lib/transport/sender/xhr-cors.js
index 04d0052..cfc9bb4 100644
--- a/lib/transport/sender/xhr-cors.js
+++ b/lib/transport/sender/xhr-cors.js
@@ -1,7 +1,7 @@
'use strict';
var util = require('util')
- , AbstractXHRObject = require('./abstract-xhr')
+ , XhrDriver = require('../driver/xhr')
;
function XHRCorsObject(method, url, payload, opts) {
@@ -9,10 +9,12 @@ function XHRCorsObject(method, url, payload, opts) {
, args = arguments
;
process.nextTick(function(){
- AbstractXHRObject.apply(self, args);
+ XhrDriver.apply(self, args);
});
}
-util.inherits(XHRCorsObject, AbstractXHRObject);
+util.inherits(XHRCorsObject, XhrDriver);
+
+XHRCorsObject.enabled = XhrDriver.enabled && XhrDriver.supportsCORS;
module.exports = XHRCorsObject;
diff --git a/lib/transport/sender/xhr-fake.js b/lib/transport/sender/xhr-fake.js
index 360f08d..beabdfc 100644
--- a/lib/transport/sender/xhr-fake.js
+++ b/lib/transport/sender/xhr-fake.js
@@ -5,6 +5,7 @@ var EventEmitter = require('events').EventEmitter
;
function XHRFake(method, url, payload, opts) {
+ var self = this;
EventEmitter.call(this);
setTimeout(function() {
diff --git a/lib/transport/sender/xhr-local.js b/lib/transport/sender/xhr-local.js
index 654da17..f047941 100644
--- a/lib/transport/sender/xhr-local.js
+++ b/lib/transport/sender/xhr-local.js
@@ -1,18 +1,20 @@
'use strict';
var util = require('util')
- , AbstractXHRObject = require('./abstract-xhr')
+ , XhrDriver = require('../driver/xhr')
;
function XHRLocalObject(method, url, payload) {
var self = this;
process.nextTick(function(){
- AbstractXHRObject.call(self, method, url, payload, {
+ XhrDriver.call(self, method, url, payload, {
noCredentials: true
});
});
}
-util.inherits(XHRLocalObject, AbstractXHRObject);
+util.inherits(XHRLocalObject, XhrDriver);
+
+XHRLocalObject.enabled = XhrDriver.enabled;
module.exports = XHRLocalObject;
diff --git a/lib/transport/xdr-polling.js b/lib/transport/xdr-polling.js
index 34f717d..cfdbf54 100644
--- a/lib/transport/xdr-polling.js
+++ b/lib/transport/xdr-polling.js
@@ -7,7 +7,7 @@ var util = require('util')
, XDRObject = require('./sender/xdr')
;
-function XdrPollingTransport(ri, transUrl) {
+function XdrPollingTransport(transUrl) {
AjaxBasedTransport.call(this, transUrl, '/xhr', XhrReceiver, XDRObject);
}
diff --git a/lib/transport/xhr-polling.js b/lib/transport/xhr-polling.js
index d4822c5..6202b60 100644
--- a/lib/transport/xhr-polling.js
+++ b/lib/transport/xhr-polling.js
@@ -4,10 +4,11 @@ var util = require('util')
, AjaxBasedTransport = require('./lib/ajax-based')
, XhrReceiver = require('./receiver/xhr')
, XHRCorsObject = require('./sender/xhr-cors')
+ , XHRLocalObject = require('./sender/xhr-local')
, utils = require('../utils')
;
-function XhrPollingTransport(ri, transUrl) {
+function XhrPollingTransport(transUrl) {
AjaxBasedTransport.call(this, transUrl, '/xhr', XhrReceiver, XHRCorsObject);
}
@@ -17,10 +18,11 @@ XhrPollingTransport.enabled = function(url, info) {
if (info.nullOrigin) {
return false;
}
- if (global.XMLHttpRequest && utils.isSameOriginUrl(url)) {
+
+ if (XHRLocalObject.enabled && utils.isSameOriginUrl(url)) {
return true;
}
- return utils.isXHRCorsCapable() === 1;
+ return XHRCorsObject.enabled;
};
XhrPollingTransport.transportName = 'xhr-polling';
diff --git a/lib/transport/xhr-streaming.js b/lib/transport/xhr-streaming.js
index c54809e..6cc2f3e 100644
--- a/lib/transport/xhr-streaming.js
+++ b/lib/transport/xhr-streaming.js
@@ -4,10 +4,11 @@ var util = require('util')
, AjaxBasedTransport = require('./lib/ajax-based')
, XhrReceiver = require('./receiver/xhr')
, XHRCorsObject = require('./sender/xhr-cors')
+ , XHRLocalObject = require('./sender/xhr-local')
, utils = require('../utils')
;
-function XhrStreamingTransport(ri, transUrl) {
+function XhrStreamingTransport(transUrl) {
AjaxBasedTransport.call(this, transUrl, '/xhr_streaming', XhrReceiver, XHRCorsObject);
}
@@ -18,14 +19,14 @@ XhrStreamingTransport.enabled = function(url, info) {
return false;
}
// Opera doesn't support xhr-streaming
- if (/opera/i.test(global.navigator.userAgent)) {
+ if (global.navigator && /opera/i.test(global.navigator.userAgent)) {
return false;
}
- if (global.XMLHttpRequest && utils.isSameOriginUrl(url)) {
+
+ if (XHRLocalObject.enabled && utils.isSameOriginUrl(url)) {
return true;
}
-
- return utils.isXHRCorsCapable() === 1;
+ return XHRCorsObject.enabled;
};
XhrStreamingTransport.transportName = 'xhr-streaming';
diff --git a/package.json b/package.json
index c3619de..f909e3f 100644
--- a/package.json
+++ b/package.json
@@ -2,9 +2,10 @@
"name": "sockjs-client",
"description": "SockJS-client is a browser JavaScript library that provides a WebSocket-like object. SockJS gives you a coherent, cross-browser, Javascript API which creates a low latency, full duplex, cross-domain communication channel between the browser and the web server.",
"version": "1.0.0-alpha1",
- "author": "Marek Majkowski",
+ "author": "Bryce Kahle",
"browser": {
- "./lib/transport/driver/websocket": "./lib/transport/browser/websocket"
+ "./lib/transport/driver/websocket": "./lib/transport/browser/websocket",
+ "./lib/transport/driver/xhr": "./lib/transport/browser/abstract-xhr"
},
"bugs": {
"url": "https://github.com/sockjs/sockjs-client/issues"
@@ -13,6 +14,10 @@
{
"name": "Bryce Kahle",
"email": "bkahle at gmail.com"
+ },
+ {
+ "name": "Marek Majkowski",
+ "email": "deadbeef at popcount.org"
}
],
"dependencies": {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/sockjs-client.git
More information about the Pkg-javascript-commits
mailing list