Socket
Socket
Sign inDemoInstall

eventsource

Package Overview
Dependencies
0
Maintainers
1
Versions
35
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.10 to 0.1.0

11

History.md

@@ -0,1 +1,6 @@

# [0.1.0](https://github.com/aslakhellesoy/eventsource-node/compare/v0.0.10...0.1.0)
* Bugfix: High CPU usage by replacing Jison with port of WebKit's parser. ([#25](https://github.com/aslakhellesoy/eventsource-node/issues/25), [#32](https://github.com/aslakhellesoy/eventsource-node/pull/32), [#18](https://github.com/aslakhellesoy/eventsource-node/issues/18) qqueue)
* Reformatted all code to 2 spaces.
# [0.0.10](https://github.com/aslakhellesoy/eventsource-node/compare/v0.0.9...v0.0.10)

@@ -8,7 +13,7 @@

* Bugfix: old "last-event-id" used on reconnect ([#27](https://github.com/aslakhellesoy/eventsource-node/pull/27) Aslak Hellesøy)
* Bugfix: old "last-event-id" used on reconnect ([#27](https://github.com/aslakhellesoy/eventsource-node/pull/27) Aslak Hellesøy)
# [0.0.8](https://github.com/aslakhellesoy/eventsource-node/compare/v0.0.7...v0.0.8)
* Bugfix: EventSource still reconnected when closed ([#24](https://github.com/aslakhellesoy/eventsource-node/pull/24) FrozenCow)
* Bugfix: EventSource still reconnected when closed ([#24](https://github.com/aslakhellesoy/eventsource-node/pull/24) FrozenCow)
* Allow unauthorized HTTPS connections by setting `rejectUnauthorized` to false. (Aslak Hellesøy)

@@ -18,3 +23,3 @@

* Explicitly raise an error when server returns http 403 and dont continue ([#20](https://github.com/aslakhellesoy/eventsource-node/pull/20) Scott Moak)
* Explicitly raise an error when server returns http 403 and don't continue ([#20](https://github.com/aslakhellesoy/eventsource-node/pull/20) Scott Moak)
* Added ability to send custom http headers to server ([#21](https://github.com/aslakhellesoy/eventsource-node/pull/21), [#9](https://github.com/aslakhellesoy/eventsource-node/issues/9) Scott Moak)

@@ -21,0 +26,0 @@ * Fix Unicode support to cope with Javascript Unicode size limitations ([#23](https://github.com/aslakhellesoy/eventsource-node/pull/23), [#22](https://github.com/aslakhellesoy/eventsource-node/issues/22) Devon Adkisson)

var http = require('http')
, https =require('https')
, https = require('https')
, util = require('util')
, events = require('events')
, eventstream = require('./eventstream');
, events = require('events');
function isPlainObject(obj) {
return Object.getPrototypeOf(obj) === Object.prototype;
return Object.getPrototypeOf(obj) === Object.prototype;
}

@@ -19,138 +18,208 @@

function EventSource(url, eventSourceInitDict) {
var readyState = EventSource.CONNECTING;
Object.defineProperty(this, 'readyState', {
get: function() {
return readyState;
}
});
var readyState = EventSource.CONNECTING;
Object.defineProperty(this, 'readyState', {
get: function () {
return readyState;
}
});
Object.defineProperty(this, 'url', {
get: function() {
return url;
}
});
Object.defineProperty(this, 'url', {
get: function () {
return url;
}
});
var self = this;
self.reconnectInterval = 1000;
var connectPending = false;
var self = this;
self.reconnectInterval = 1000;
var connectPending = false;
function onConnectionClosed(err) {
if (connectPending || readyState === EventSource.CLOSED) return;
connectPending = true;
readyState = EventSource.CONNECTING;
_emit('error', new Event('error'));
function onConnectionClosed() {
if (connectPending || readyState === EventSource.CLOSED) return;
connectPending = true;
readyState = EventSource.CONNECTING;
_emit('error', new Event('error'));
// The url may have been changed by a temporary
// redirect. If that's the case, revert it now.
if (reconnectUrl) {
url = reconnectUrl;
reconnectUrl = null;
}
setTimeout(function() {
if (readyState !== EventSource.CONNECTING) {
return;
}
connect();
}, self.reconnectInterval);
// The url may have been changed by a temporary
// redirect. If that's the case, revert it now.
if (reconnectUrl) {
url = reconnectUrl;
reconnectUrl = null;
}
setTimeout(function () {
if (readyState !== EventSource.CONNECTING) {
return;
}
connect();
}, self.reconnectInterval);
}
var req;
var lastEventId = '';
if (eventSourceInitDict && eventSourceInitDict.headers && isPlainObject(eventSourceInitDict.headers) && eventSourceInitDict.headers['Last-Event-ID']) {
lastEventId = eventSourceInitDict.headers['Last-Event-ID'];
delete eventSourceInitDict.headers['Last-Event-ID'];
var req;
var lastEventId = '';
if (eventSourceInitDict && eventSourceInitDict.headers && isPlainObject(eventSourceInitDict.headers) && eventSourceInitDict.headers['Last-Event-ID']) {
lastEventId = eventSourceInitDict.headers['Last-Event-ID'];
delete eventSourceInitDict.headers['Last-Event-ID'];
}
var discardTrailingNewline = false
, data = ''
, eventName = '';
var reconnectUrl = null;
function connect() {
connectPending = false;
var options = require('url').parse(url);
var isSecure = options.protocol == 'https:';
options.headers = { 'Cache-Control': 'no-cache', 'Accept': 'text/event-stream' };
if (lastEventId) options.headers['Last-Event-ID'] = lastEventId;
if (eventSourceInitDict && eventSourceInitDict.headers && isPlainObject(eventSourceInitDict.headers)) {
for (var i in eventSourceInitDict.headers) {
var header = eventSourceInitDict.headers[i];
options.headers[i] = header;
}
}
var reconnectUrl = null;
options.rejectUnauthorized = !(eventSourceInitDict && eventSourceInitDict.rejectUnauthorized == false);
function connect() {
connectPending = false;
var options = require('url').parse(url);
var isSecure = options.protocol == 'https:';
options.headers = { 'Cache-Control': 'no-cache', 'Accept': 'text/event-stream' };
if (lastEventId) options.headers['Last-Event-ID'] = lastEventId;
if (eventSourceInitDict && eventSourceInitDict.headers && isPlainObject(eventSourceInitDict.headers)) {
for (var i in eventSourceInitDict.headers) {
var header = eventSourceInitDict.headers[i];
options.headers[i] = header;
}
req = (isSecure ? https : http).request(options, function (res) {
// Handle HTTP redirects
if (res.statusCode == 301 || res.statusCode == 307) {
if (!res.headers.location) {
// Server sent redirect response without Location header.
_emit('error', new Event('error'));
return;
}
options.rejectUnauthorized = true;
if(eventSourceInitDict && eventSourceInitDict.rejectUnauthorized == false) {
options.rejectUnauthorized = false;
}
if (res.statusCode == 307) reconnectUrl = url;
url = res.headers.location;
process.nextTick(connect);
return;
}
req = (isSecure ? https : http).request(options, function(res) {
// Handle HTTP redirects
if (res.statusCode == 301 || res.statusCode == 307) {
if (!res.headers.location) {
// Server sent redirect response without Location header.
_emit('error', new Event('error'));
return;
}
if (res.statusCode == 307) reconnectUrl = url;
url = res.headers.location;
process.nextTick(connect);
return;
if (res.statusCode == 204) return self.close();
if (res.statusCode == 403) {
// 'Access denied'
_emit('error', new Event('error'));
return self.close();
}
readyState = EventSource.OPEN;
res.on('close', onConnectionClosed);
res.on('end', onConnectionClosed);
_emit('open', new Event('open'));
// text/event-stream parser adapted from webkit's
// Source/WebCore/page/EventSource.cpp
var buf = '';
res.on('data', function (chunk) {
buf += chunk;
var pos = 0
, length = buf.length;
while (pos < length) {
if (discardTrailingNewline) {
if (buf[pos] === '\n') {
++pos;
}
discardTrailingNewline = false;
}
if (res.statusCode == 204) return self.close();
var lineLength = -1
, fieldLength = -1
, c;
if (res.statusCode == 403) {
// 'Access denied'
_emit('error', new Event('error'));
return self.close();
for (var i = pos; lineLength < 0 && i < length; ++i) {
c = buf[i];
if (c === ':') {
if (fieldLength < 0) {
fieldLength = i - pos;
}
} else if (c === '\r') {
discardTrailingNewline = true;
lineLength = i - pos;
} else if (c === '\n') {
lineLength = i - pos;
}
}
readyState = EventSource.OPEN;
res.on('close', onConnectionClosed);
res.on('end', onConnectionClosed);
_emit('open', new Event('open'));
if (lineLength < 0) {
break;
}
var buf = '';
res.on('data', function (chunk) {
buf = buf + chunk;
var messages = buf.match(/(.|\r\n|\n|\r)*(\n\n|\r\r|\r\n\r\n)/);
if (!messages) return;
messages = messages[0];
buf = buf.slice(messages.length);
try {
messages = eventstream.parse(messages);
if (!messages) return;
messages.forEach(function(message) {
var data = message.data.replace(/\n$/, '');
if (data == '' || (message.event != null && message.event == '')) {
return;
}
if (message.id) lastEventId = message.id;
var type = message.event || 'message';
_emit(type, new MessageEvent('message', {
data: data,
lastEventId: lastEventId
}));
});
} catch(e) {
_emit('error', new Event('error'));
}
});
});
parseEventStreamLine(buf, pos, fieldLength, lineLength);
req.on('error', onConnectionClosed);
req.setNoDelay(true);
req.end();
}
connect();
pos += lineLength + 1;
}
function _emit() {
if(self.listeners(arguments[0]).length > 0) {
self.emit.apply(self, arguments);
if (pos === length) {
buf = '';
} else if (pos > 0) {
buf = buf.slice(pos);
}
});
});
req.on('error', onConnectionClosed);
req.setNoDelay(true);
req.end();
}
connect();
function _emit() {
if (self.listeners(arguments[0]).length > 0) {
self.emit.apply(self, arguments);
}
}
this.close = function() {
if (readyState == EventSource.CLOSED) return;
readyState = EventSource.CLOSED;
req.abort();
this.close = function () {
if (readyState == EventSource.CLOSED) return;
readyState = EventSource.CLOSED;
req.abort();
};
function parseEventStreamLine(buf, pos, fieldLength, lineLength) {
if (lineLength === 0) {
if (data.length > 0) {
var type = eventName || 'message';
_emit(type, new MessageEvent('message', {
data: data.slice(0, -1), // remove trailing newline
lastEventId: lastEventId
}));
data = '';
}
eventName = void 0;
} else if (fieldLength > 0) {
var noValue = fieldLength < 0
, step = 0
, field = buf.slice(pos, pos + (noValue ? lineLength : fieldLength));
if (noValue) {
step = lineLength;
} else if (buf[pos + fieldLength + 1] !== ' ') {
step = fieldLength + 1;
} else {
step = fieldLength + 2;
}
pos += step;
var valueLength = lineLength - step
, value = buf.slice(pos, pos + valueLength);
if (field === 'data') {
if (value.length > 0) {
data += value + '\n';
}
} else if (field === 'event') {
eventName = value;
} else if (field === 'id') {
lastEventId = value;
} else if (field === 'retry') {
var retry = parseInt(value, 10);
if (!Number.isNaN(retry)) {
self.reconnectInterval = retry;
}
}
}
}
}

@@ -163,27 +232,27 @@

['open', 'error', 'message'].forEach(function(method) {
Object.defineProperty(EventSource.prototype, 'on' + method, {
/**
* Returns the current listener
*
* @return {Mixed} the set function or undefined
* @api private
*/
get: function get() {
var listener = this.listeners(method)[0];
return listener ? (listener._listener ? listener._listener : listener) : undefined;
},
['open', 'error', 'message'].forEach(function (method) {
Object.defineProperty(EventSource.prototype, 'on' + method, {
/**
* Returns the current listener
*
* @return {Mixed} the set function or undefined
* @api private
*/
get: function get() {
var listener = this.listeners(method)[0];
return listener ? (listener._listener ? listener._listener : listener) : undefined;
},
/**
* Start listening for events
*
* @param {Function} listener the listener
* @return {Mixed} the set function or undefined
* @api private
*/
set: function set(listener) {
this.removeAllListeners(method);
this.addEventListener(method, listener);
}
});
/**
* Start listening for events
*
* @param {Function} listener the listener
* @return {Mixed} the set function or undefined
* @api private
*/
set: function set(listener) {
this.removeAllListeners(method);
this.addEventListener(method, listener);
}
});
});

@@ -198,3 +267,2 @@

/**

@@ -204,3 +272,3 @@ * Emulates the W3C Browser based WebSocket interface using addEventListener.

* @param {String} method Listen for an event
* @param {Function} event callback
* @param {Function} listener callback
* @see https://developer.mozilla.org/en/DOM/element.addEventListener

@@ -211,7 +279,7 @@ * @see http://dev.w3.org/html5/websockets/#the-websocket-interface

EventSource.prototype.addEventListener = function addEventListener(method, listener) {
if (typeof listener === 'function') {
// store a reference so we can return the original function again
listener._listener = listener;
this.on(method, listener);
}
if (typeof listener === 'function') {
// store a reference so we can return the original function again
listener._listener = listener;
this.on(method, listener);
}
};

@@ -226,3 +294,3 @@

function Event(type) {
Object.defineProperty(this, 'type', { writable: false, value: type });
Object.defineProperty(this, 'type', { writable: false, value: type });
}

@@ -237,9 +305,9 @@

function MessageEvent(type, eventInitDict) {
Object.defineProperty(this, 'type', { writable: false, value: type });
for(var f in eventInitDict) {
if(eventInitDict.hasOwnProperty(f)) {
Object.defineProperty(this, f, { writable: false, value: eventInitDict[f] });
}
Object.defineProperty(this, 'type', { writable: false, value: type });
for (var f in eventInitDict) {
if (eventInitDict.hasOwnProperty(f)) {
Object.defineProperty(this, f, { writable: false, value: eventInitDict[f] });
}
}
}
{
"name": "eventsource",
"version": "0.0.10",
"version": "0.1.0",
"description": "W3C compliant EventSource client for Node.js",

@@ -20,3 +20,5 @@ "keywords": [

"Devon Adkisson",
"FrozenCow <frozencow@gmail.com>"
"FrozenCow <frozencow@gmail.com>",
"mbieser <29erpilot@gmail.com>",
"qqueue <queue@hakase.org>"
],

@@ -41,7 +43,6 @@ "repository": {

"devDependencies": {
"mocha": "~1.9.0",
"jison": "~0.4.4"
"mocha": "~1.17.1"
},
"scripts": {
"test": "make run-tests"
"test": "./node_modules/.bin/mocha --reporter spec"
},

@@ -48,0 +49,0 @@ "engines": {

@@ -9,843 +9,872 @@ var EventSource = require('../lib/eventsource')

var servers = 0;
process.on('exit', function() {
if(servers != 0) {
console.error("************ Didn't kill all servers - there is still %d running.", servers);
}
process.on('exit', function () {
if (servers != 0) {
console.error("************ Didn't kill all servers - there is still %d running.", servers);
}
});
function createServer(chunks, callback, onreq, secure) {
var options = {};
var isSecure = onreq === true || secure === true;
if (isSecure) {
options = {
key: fs.readFileSync(__dirname + '/key.pem'),
cert: fs.readFileSync(__dirname + '/certificate.pem')
};
}
var responses = [];
function open(req, res) {
if (typeof onreq == 'function' && onreq(req, res) === true) return;
res.writeHead(200, {'Content-Type': 'text/event-stream'});
chunks.forEach(function(chunk) { res.write(chunk); });
res.write(':'); // send a dummy comment to ensure that the head is flushed
responses.push(res);
}
function close(closed) {
responses.forEach(function(res) {
res.end();
});
server.on('close', closed);
server.close();
}
var server;
if (isSecure) server = https.createServer(options, open);
else server = http.createServer(open);
server.listen(_port, function onOpen() {
servers++;
callback(_port++, function(err) {
servers--;
close(err);
});
var options = {};
var isSecure = onreq === true || secure === true;
if (isSecure) {
options = {
key: fs.readFileSync(__dirname + '/key.pem'),
cert: fs.readFileSync(__dirname + '/certificate.pem')
};
}
var responses = [];
function open(req, res) {
if (typeof onreq == 'function' && onreq(req, res) === true) return;
res.writeHead(200, {'Content-Type': 'text/event-stream'});
chunks.forEach(function (chunk) {
res.write(chunk);
});
};
res.write(':'); // send a dummy comment to ensure that the head is flushed
responses.push(res);
}
describe('Parser', function() {
it('parses multibyte characters', function(done) {
createServer(["id: 1\ndata: €豆腐\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function(m) {
assert.equal("€豆腐", m.data);
es.close();
close(done);
};
});
function close(closed) {
responses.forEach(function (res) {
res.end();
});
server.on('close', closed);
server.close();
}
it('raises error when it fails to parse', function(done) {
createServer(["\n\n\n\nid: 1\ndata: hello world\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function(m) {
assert.equal("hello world", m.data);
es.close();
close(done);
};
es.onerror = function(e) {
es.close();
close(done);
};
});
var server;
if (isSecure) server = https.createServer(options, open);
else server = http.createServer(open);
server.listen(_port, function onOpen() {
servers++;
callback(_port++, function (err) {
servers--;
close(err);
});
});
}
it('parses one one-line message in one chunk', function(done) {
createServer(["data: Hello\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function(m) {
assert.equal("Hello", m.data);
es.close();
close(done);
};
});
describe('Parser', function () {
it('parses multibyte characters', function (done) {
createServer(["id: 1\ndata: €豆腐\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function (m) {
assert.equal("€豆腐", m.data);
es.close();
close(done);
};
});
});
it('parses one one-line message in two chunks', function(done) {
createServer(["data: Hel", "lo\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function(m) {
assert.equal("Hello", m.data);
es.close();
close(done);
};
});
it('parses empty lines with multibyte characters', function (done) {
createServer(["\n\n\n\nid: 1\ndata: 我現在都看實況不玩遊戲\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function (m) {
assert.equal("我現在都看實況不玩遊戲", m.data);
es.close();
close(done);
};
});
});
it('parses two one-line messages in one chunk', function(done) {
createServer(["data: Hello\n\n", "data: World\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
it('parses one one-line message in one chunk', function (done) {
createServer(["data: Hello\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function (m) {
assert.equal("Hello", m.data);
es.close();
close(done);
};
});
});
function first(m) {
assert.equal("Hello", m.data);
es.onmessage = second;
}
it('parses one one-line message in two chunks', function (done) {
createServer(["data: Hel", "lo\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function (m) {
assert.equal("Hello", m.data);
es.close();
close(done);
};
});
});
function second(m) {
assert.equal("World", m.data);
es.close();
close(done);
}
});
it('parses two one-line messages in one chunk', function (done) {
createServer(["data: Hello\n\n", "data: World\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
function first(m) {
assert.equal("Hello", m.data);
es.onmessage = second;
}
function second(m) {
assert.equal("World", m.data);
es.close();
close(done);
}
});
});
it('parses one two-line message in one chunk', function(done) {
createServer(["data: Hello\ndata:World\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function(m) {
assert.equal("Hello\nWorld", m.data);
es.close();
close(done);
};
});
it('parses one two-line message in one chunk', function (done) {
createServer(["data: Hello\ndata:World\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function (m) {
assert.equal("Hello\nWorld", m.data);
es.close();
close(done);
};
});
});
it('parses really chopped up unicode data', function(done) {
var chopped = "data: Aslak\n\ndata: Hellesøy\n\n".split("");
createServer(chopped, function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
it('parses really chopped up unicode data', function (done) {
var chopped = "data: Aslak\n\ndata: Hellesøy\n\n".split("");
createServer(chopped, function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
function first(m) {
assert.equal("Aslak", m.data);
es.onmessage = second;
}
function first(m) {
assert.equal("Aslak", m.data);
es.onmessage = second;
}
function second(m) {
assert.equal("Hellesøy", m.data);
es.close();
close(done);
}
});
function second(m) {
assert.equal("Hellesøy", m.data);
es.close();
close(done);
}
});
});
it('accepts CRLF as separator', function(done) {
var chopped = "data: Aslak\r\n\r\ndata: Hellesøy\r\n\r\n".split("");
createServer(chopped, function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
it('accepts CRLF as separator', function (done) {
var chopped = "data: Aslak\r\n\r\ndata: Hellesøy\r\n\r\n".split("");
createServer(chopped, function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
function first(m) {
assert.equal("Aslak", m.data);
es.onmessage = second;
}
function first(m) {
assert.equal("Aslak", m.data);
es.onmessage = second;
}
function second(m) {
assert.equal("Hellesøy", m.data);
es.close();
close(done);
}
});
function second(m) {
assert.equal("Hellesøy", m.data);
es.close();
close(done);
}
});
});
it('accepts CR as separator', function(done) {
var chopped = "data: Aslak\r\rdata: Hellesøy\r\r".split("");
createServer(chopped, function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
it('accepts CR as separator', function (done) {
var chopped = "data: Aslak\r\rdata: Hellesøy\r\r".split("");
createServer(chopped, function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
function first(m) {
assert.equal("Aslak", m.data);
es.onmessage = second;
}
function first(m) {
assert.equal("Aslak", m.data);
es.onmessage = second;
}
function second(m) {
assert.equal("Hellesøy", m.data);
es.close();
close(done);
}
});
function second(m) {
assert.equal("Hellesøy", m.data);
es.close();
close(done);
}
});
});
it('delivers message with explicit event', function(done) {
createServer(["event: greeting\ndata: Hello\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.addEventListener('greeting', function(m) {
assert.equal("Hello", m.data);
es.close();
close(done);
});
});
it('delivers message with explicit event', function (done) {
createServer(["event: greeting\ndata: Hello\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.addEventListener('greeting', function (m) {
assert.equal("Hello", m.data);
es.close();
close(done);
});
});
});
it('ignores comments', function(done) {
createServer(["data: Hello\n\n:nothing to see here\n\ndata: World\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
it('ignores comments', function (done) {
createServer(["data: Hello\n\n:nothing to see here\n\ndata: World\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
function first(m) {
assert.equal("Hello", m.data);
es.onmessage = second;
}
function first(m) {
assert.equal("Hello", m.data);
es.onmessage = second;
}
function second(m) {
assert.equal("World", m.data);
es.close();
close(done);
}
});
function second(m) {
assert.equal("World", m.data);
es.close();
close(done);
}
});
});
it('ignores empty comments', function(done) {
createServer(["data: Hello\n\n:\n\ndata: World\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
it('ignores empty comments', function (done) {
createServer(["data: Hello\n\n:\n\ndata: World\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
function first(m) {
assert.equal("Hello", m.data);
es.onmessage = second;
}
function first(m) {
assert.equal("Hello", m.data);
es.onmessage = second;
}
function second(m) {
assert.equal("World", m.data);
es.close();
close(done);
}
});
function second(m) {
assert.equal("World", m.data);
es.close();
close(done);
}
});
});
it('causes entire event to be ignored for empty data fields', function(done) {
createServer(["data:\n\ndata: Hello\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
var originalEmit = es.emit;
es.emit = function(event) {
assert.ok(event === 'message' || event === 'newListener');
return originalEmit.apply(this, arguments);
}
es.onmessage = function(m) {
assert.equal('Hello', m.data);
es.close();
close(done);
};
});
it('causes entire event to be ignored for empty data fields', function (done) {
createServer(["data:\n\ndata: Hello\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
var originalEmit = es.emit;
es.emit = function (event) {
assert.ok(event === 'message' || event === 'newListener');
return originalEmit.apply(this, arguments);
};
es.onmessage = function (m) {
assert.equal('Hello', m.data);
es.close();
close(done);
};
});
});
it('causes entire event to be ignored for empty event field', function(done) {
createServer(["event:\n\ndata: Hello\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
var originalEmit = es.emit;
es.emit = function(event) {
assert.ok(event === 'message' || event === 'newListener');
return originalEmit.apply(this, arguments);
}
es.onmessage = function(m) {
assert.equal('Hello', m.data);
es.close();
close(done);
};
});
it('causes entire event to be ignored for empty event field', function (done) {
createServer(["event:\n\ndata: Hello\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
var originalEmit = es.emit;
es.emit = function (event) {
assert.ok(event === 'message' || event === 'newListener');
return originalEmit.apply(this, arguments);
};
es.onmessage = function (m) {
assert.equal('Hello', m.data);
es.close();
close(done);
};
});
});
var longMessage = "data: " + new Array(100000).join('a') + "\n\n";
it('parses relatively huge messages efficiently', function (done) {
this.timeout(1000);
createServer([longMessage], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function () {
es.close();
close(done);
};
});
});
});
describe('HTTP Request', function() {
it('passes cache-control: no-cache to server', function(done) {
var headers;
createServer([], function(port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url);
es.onopen = function() {
assert.equal('no-cache', headers['cache-control']);
es.close();
close(done);
};
}, function(req) { headers = req.headers; });
describe('HTTP Request', function () {
it('passes cache-control: no-cache to server', function (done) {
var headers;
createServer([], function (port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url);
es.onopen = function () {
assert.equal('no-cache', headers['cache-control']);
es.close();
close(done);
};
}, function (req) {
headers = req.headers;
});
});
it('sets headers by user', function(done) {
var headers = {
'User-Agent': 'test',
'Cookie': 'test=test',
'Last-Event-ID': '99'
it('sets headers by user', function (done) {
var headers = {
'User-Agent': 'test',
'Cookie': 'test=test',
'Last-Event-ID': '99'
};
createServer([],
function (port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url, {headers: headers});
es.onopen = function () {
es.close();
close(done);
};
createServer([],
function(port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url, {headers: headers});
es.onopen = function() {
es.close();
close(done);
};
},
function(req, res) {
assert.equal(req.headers['user-agent'], headers['User-Agent']);
assert.equal(req.headers['cookie'], headers['Cookie']);
assert.equal(req.headers['last-event-id'], '99'); // Shouldn't be sent
res.writeHead(200);
res.end();
return true;
});
});
},
function (req, res) {
assert.equal(req.headers['user-agent'], headers['User-Agent']);
assert.equal(req.headers['cookie'], headers['Cookie']);
assert.equal(req.headers['last-event-id'], '99'); // Shouldn't be sent
res.writeHead(200);
res.end();
return true;
});
});
it('follows http 301 redirect', function(done) {
var url = 'http://localhost:' + _port;
var redirectSuffix = '/foobar';
var clientRequestedRedirectUrl = false;
createServer([],
function(port, close) {
var es = new EventSource(url);
es.onopen = function() {
assert.ok(clientRequestedRedirectUrl);
assert.equal(url + redirectSuffix, es.url);
es.close();
close(done);
};
},
function(req, res) {
if (req.url != '/') {
clientRequestedRedirectUrl = req.url == redirectSuffix;
return false;
}
res.writeHead(301, 'Moved Permanently', {
'Connection': 'Close',
'Location': url + redirectSuffix
});
res.end();
return true;
});
});
it('follows http 301 redirect', function (done) {
var url = 'http://localhost:' + _port;
var redirectSuffix = '/foobar';
var clientRequestedRedirectUrl = false;
createServer([],
function (port, close) {
var es = new EventSource(url);
es.onopen = function () {
assert.ok(clientRequestedRedirectUrl);
assert.equal(url + redirectSuffix, es.url);
es.close();
close(done);
};
},
function (req, res) {
if (req.url != '/') {
clientRequestedRedirectUrl = req.url == redirectSuffix;
return false;
}
res.writeHead(301, 'Moved Permanently', {
'Connection': 'Close',
'Location': url + redirectSuffix
});
res.end();
return true;
});
});
it('causes error event when response is 403', function(done) {
createServer(["id: 1\ndata: hello world\n\n"],
function(port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url);
es.onerror = function() {
assert.ok(true, 'got error');
es.close();
close(done);
};
},
function(req, res) {
res.writeHead(403, {'Content-Type': 'text/html'});
res.end();
});
});
it('causes error event when response is 403', function (done) {
createServer(["id: 1\ndata: hello world\n\n"],
function (port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url);
es.onerror = function () {
assert.ok(true, 'got error');
es.close();
close(done);
};
},
function (req, res) {
res.writeHead(403, {'Content-Type': 'text/html'});
res.end();
});
});
it('causes error event when response is 301 with missing location', function(done) {
createServer([],
function(port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url);
es.onerror = function() {
es.close();
close(done);
};
},
function(req, res) {
if (req.url != '/') return false;
res.writeHead(301, 'Moved Permanently', {
'Connection': 'Close'
});
res.end();
return true;
});
});
it('causes error event when response is 301 with missing location', function (done) {
createServer([],
function (port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url);
es.onerror = function () {
es.close();
close(done);
};
},
function (req, res) {
if (req.url != '/') return false;
res.writeHead(301, 'Moved Permanently', {
'Connection': 'Close'
});
res.end();
return true;
});
});
it('follows http 307 redirect', function(done) {
var url = 'http://localhost:' + _port;
var redirectSuffix = '/foobar';
var clientRequestedRedirectUrl = false;
createServer([],
function(port, close) {
var es = new EventSource(url);
es.onopen = function() {
assert.ok(clientRequestedRedirectUrl);
assert.equal(url + redirectSuffix, es.url);
es.close();
close(done);
};
},
function(req, res) {
if (req.url != '/') {
clientRequestedRedirectUrl = req.url == redirectSuffix;
return false;
}
res.writeHead(307, 'Temporary Redirect', {
'Connection': 'Close',
'Location': url + redirectSuffix
});
res.end();
return true;
});
});
it('follows http 307 redirect', function (done) {
var url = 'http://localhost:' + _port;
var redirectSuffix = '/foobar';
var clientRequestedRedirectUrl = false;
createServer([],
function (port, close) {
var es = new EventSource(url);
es.onopen = function () {
assert.ok(clientRequestedRedirectUrl);
assert.equal(url + redirectSuffix, es.url);
es.close();
close(done);
};
},
function (req, res) {
if (req.url != '/') {
clientRequestedRedirectUrl = req.url == redirectSuffix;
return false;
}
res.writeHead(307, 'Temporary Redirect', {
'Connection': 'Close',
'Location': url + redirectSuffix
});
res.end();
return true;
});
});
it('causes error event for 307 response with with missing location', function(done) {
createServer([],
function(port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url);
es.onerror = function() {
es.close();
close(done);
};
},
function(req, res) {
if (req.url != '/') return false;
res.writeHead(307, 'Temporary Redirect', {
'Connection': 'Close'
});
res.end();
return true;
});
});
it('causes error event for 307 response with with missing location', function (done) {
createServer([],
function (port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url);
es.onerror = function () {
es.close();
close(done);
};
},
function (req, res) {
if (req.url != '/') return false;
res.writeHead(307, 'Temporary Redirect', {
'Connection': 'Close'
});
res.end();
return true;
});
});
});
describe('HTTPS Support', function() {
it('uses https for https urls', function(done) {
var chopped = "data: Aslak\n\ndata: Hellesøy\n\n".split("");
createServer(chopped, function(port, close) {
var es = new EventSource('https://localhost:' + port, {rejectUnauthorized: false});
es.onerror = function(err) {
if(!err) err = new Error("Didn't expect error here");
done(err);
};
es.onmessage = first;
describe('HTTPS Support', function () {
it('uses https for https urls', function (done) {
var chopped = "data: Aslak\n\ndata: Hellesøy\n\n".split("");
createServer(chopped, function (port, close) {
var es = new EventSource('https://localhost:' + port, {rejectUnauthorized: false});
function first(m) {
assert.equal("Aslak", m.data);
es.onmessage = second;
}
es.onerror = function (err) {
if (!err) err = new Error("Didn't expect error here");
done(err);
};
es.onmessage = first;
function second(m) {
assert.equal("Hellesøy", m.data);
es.close();
close(done);
}
}, true);
});
function first(m) {
assert.equal("Aslak", m.data);
es.onmessage = second;
}
if(!process.version.match(/^v0\.[12345678]\./)) {
// This functionality relies on Node 0.10.x
it('rejects unauthorized https by default', function(done) {
var chopped = "data: Aslak\n\ndata: Hellesøy\n\n".split("");
createServer(chopped, function(port, close) {
var es = new EventSource('https://localhost:' + port);
es.onerror = function(err) {
// Expected
close(done);
};
es.onmessage = function(err) {
close(function() {
done(new Error("Didn't expect any messages"));
});
};
}, true);
});
}
});
function second(m) {
assert.equal("Hellesøy", m.data);
es.close();
close(done);
}
}, true);
});
describe('Reconnection', function() {
it('is attempted when server is down', function(done) {
var es = new EventSource('http://localhost:' + _port);
es.reconnectInterval = 0;
var theClose = null;
if (!process.version.match(/^v0\.[12345678]\./)) {
// This functionality relies on Node 0.10.x
it('rejects unauthorized https by default', function (done) {
var chopped = "data: Aslak\n\ndata: Hellesøy\n\n".split("");
createServer(chopped, function (port, close) {
var es = new EventSource('https://localhost:' + port);
es.onerror = function(source) {
es.onerror = null;
createServer(["data: Hello\n\n"], function(port, close) {
theClose = close;
});
es.onerror = function (err) {
// Expected
close(done);
};
es.onmessage = function(m) {
assert.equal("Hello", m.data);
es.close();
theClose(done);
es.onmessage = function (err) {
close(function () {
done(new Error("Didn't expect any messages"));
});
};
}, true);
});
}
});
it('is attempted when server goes down after connection', function(done) {
createServer(["data: Hello\n\n"], function(port, closeFirstServer) {
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
describe('Reconnection', function () {
it('is attempted when server is down', function (done) {
var es = new EventSource('http://localhost:' + _port);
es.reconnectInterval = 0;
var theClose = null;
es.onmessage = function(m) {
assert.equal("Hello", m.data);
closeFirstServer(function() {
_port = port;
createServer(["data: World\n\n"], function(port, closeSecondServer) {
es.onmessage = second;
es.onerror = function () {
es.onerror = null;
createServer(["data: Hello\n\n"], function (port, close) {
theClose = close;
});
};
function second(m) {
assert.equal("World", m.data);
es.close();
closeSecondServer(done);
}
});
});
};
es.onmessage = function (m) {
assert.equal("Hello", m.data);
es.close();
theClose(done);
};
});
it('is attempted when server goes down after connection', function (done) {
createServer(["data: Hello\n\n"], function (port, closeFirstServer) {
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
es.onmessage = function (m) {
assert.equal("Hello", m.data);
closeFirstServer(function () {
_port = port;
createServer(["data: World\n\n"], function (port, closeSecondServer) {
es.onmessage = second;
function second(m) {
assert.equal("World", m.data);
es.close();
closeSecondServer(done);
}
});
});
};
});
});
it('is stopped when server goes down and eventsource is being closed', function(done) {
createServer(["data: Hello\n\n"], function(port, closeFirstServer) {
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
it('is stopped when server goes down and eventsource is being closed', function (done) {
createServer(["data: Hello\n\n"], function (port, closeFirstServer) {
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
es.onmessage = function(m) {
assert.equal("Hello", m.data);
closeFirstServer(function() {
// The server has closed down. es.onerror should now get called,
// because es's remote connection was dropped.
});
};
es.onmessage = function (m) {
assert.equal("Hello", m.data);
closeFirstServer(function () {
// The server has closed down. es.onerror should now get called,
// because es's remote connection was dropped.
});
};
es.onerror = function(source) {
// We received an error because the remote connection was closed.
// We close es, so we do not want es to reconnect.
es.close();
es.onerror = function () {
_port = port;
createServer(["data: World\n\n"], function(port, closeSecondServer) {
es.onmessage = second;
// We received an error because the remote connection was closed.
// We close es, so we do not want es to reconnect.
es.close();
function second(m) {
// We received a message even though we closed es.
assert.ok(false);
}
_port = port;
createServer(["data: World\n\n"], function (port, closeSecondServer) {
es.onmessage = second;
setTimeout(function() {
// We have not received any message within 100ms, we can
// presume this works correctly.
closeSecondServer(done);
},100);
});
};
function second() {
// We received a message even though we closed es.
assert.ok(false);
}
setTimeout(function () {
// We have not received any message within 100ms, we can
// presume this works correctly.
closeSecondServer(done);
}, 100);
});
};
});
});
it('is not attempted when server responds with HTTP 204', function(done) {
createServer(["data: Hello\n\n"], function(port, closeFirstServer) {
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
it('is not attempted when server responds with HTTP 204', function (done) {
createServer(["data: Hello\n\n"], function (port, closeFirstServer) {
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
es.onmessage = function(m) {
assert.equal("Hello", m.data);
closeFirstServer(function() {
_port = port;
createServer([], function(port, closeSecondServer) {
// this will be verified by the readyState
// going from CONNECTING to CLOSED,
// along with the tests verifying that the
// state is CONNECTING when a server closes.
// it's next to impossible to write a fail-safe
// test for this, though.
var ival = setInterval(function() {
if (es.readyState == EventSource.CLOSED) {
clearInterval(ival);
closeSecondServer(done);
}
}, 5);
}, function(req, res) { res.writeHead(204); res.end(); return true; });
});
};
es.onmessage = function (m) {
assert.equal("Hello", m.data);
closeFirstServer(function () {
_port = port;
createServer([], function (port, closeSecondServer) {
// this will be verified by the readyState
// going from CONNECTING to CLOSED,
// along with the tests verifying that the
// state is CONNECTING when a server closes.
// it's next to impossible to write a fail-safe
// test for this, though.
var ival = setInterval(function () {
if (es.readyState == EventSource.CLOSED) {
clearInterval(ival);
closeSecondServer(done);
}
}, 5);
}, function (req, res) {
res.writeHead(204);
res.end();
return true;
});
});
};
});
});
it('sends Last-Event-ID http header when it has previously been passed in an event from the server', function(done) {
createServer(['id: 10\ndata: Hello\n\n'], function(port, closeFirstServer) {
var headers = null;
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
it('sends Last-Event-ID http header when it has previously been passed in an event from the server', function (done) {
createServer(['id: 10\ndata: Hello\n\n'], function (port, closeFirstServer) {
var headers = null;
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
es.onmessage = function(m) {
closeFirstServer(function() {
_port = port;
createServer([], function(port, close) {
es.onopen = function() {
assert.equal('10', headers['last-event-id']);
es.close();
close(done);
};
}, function(req) { headers = req.headers; });
});
es.onmessage = function () {
closeFirstServer(function () {
_port = port;
createServer([], function (port, close) {
es.onopen = function () {
assert.equal('10', headers['last-event-id']);
es.close();
close(done);
};
}, function (req) {
headers = req.headers;
});
});
};
});
});
it('sends correct Last-Event-ID http header when an initial Last-Event-ID header was specified in the constructor', function(done) {
createServer(['id: 10\ndata: Hello\n\n'], function(port, closeFirstServer) {
var headers = null;
var es = new EventSource('http://localhost:' + port, {headers: {'Last-Event-ID': '9'}});
es.reconnectInterval = 0;
it('sends correct Last-Event-ID http header when an initial Last-Event-ID header was specified in the constructor', function (done) {
createServer(['id: 10\ndata: Hello\n\n'], function (port, closeFirstServer) {
var headers = null;
var es = new EventSource('http://localhost:' + port, {headers: {'Last-Event-ID': '9'}});
es.reconnectInterval = 0;
es.onmessage = function(m) {
closeFirstServer(function() {
_port = port;
createServer([], function(port, close) {
es.onopen = function() {
assert.equal('10', headers['last-event-id']);
es.close();
close(done);
};
}, function(req) { headers = req.headers; });
});
es.onmessage = function () {
closeFirstServer(function () {
_port = port;
createServer([], function (port, close) {
es.onopen = function () {
assert.equal('10', headers['last-event-id']);
es.close();
close(done);
};
}, function (req) {
headers = req.headers;
});
});
};
});
});
it('does not send Last-Event-ID http header when it has not been previously sent by the server', function(done) {
createServer(['data: Hello\n\n'], function(port, closeFirstServer) {
var headers = null;
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
it('does not send Last-Event-ID http header when it has not been previously sent by the server', function (done) {
createServer(['data: Hello\n\n'], function (port, closeFirstServer) {
var headers = null;
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
es.onmessage = function(m) {
closeFirstServer(function() {
_port = port;
createServer([], function(port, close) {
es.onopen = function() {
assert.equal('undefined', typeof headers['last-event-id']);
es.close();
close(done);
};
}, function(req) { headers = req.headers; });
});
es.onmessage = function () {
closeFirstServer(function () {
_port = port;
createServer([], function (port, close) {
es.onopen = function () {
assert.equal('undefined', typeof headers['last-event-id']);
es.close();
close(done);
};
}, function (req) {
headers = req.headers;
});
});
};
});
});
it('is attempted after http 301 redirect uses new url', function(done) {
var headers;
var url = 'http://localhost:' + _port;
var redirectSuffix = '/foobar';
createServer(['data: Hello\n\n'],
function(port, closeFirstServer) {
var es = new EventSource(url);
es.reconnectInterval = 0;
it('is attempted after http 301 redirect uses new url', function (done) {
var url = 'http://localhost:' + _port;
var redirectSuffix = '/foobar';
createServer(['data: Hello\n\n'],
function (port, closeFirstServer) {
var es = new EventSource(url);
es.reconnectInterval = 0;
es.onmessage = function(m) {
closeFirstServer(function() {
_port = port;
createServer([], function(port, closeSecondServer) {
es.onopen = function() {
assert.equal(url + redirectSuffix, es.url);
es.close();
closeSecondServer(done);
};
}, function(req, res) { assert.equal(redirectSuffix, req.url); });
});
};
},
function(req, res) {
if (req.url != '/') return false;
res.writeHead(301, 'Moved Permanently', {
'Connection': 'Close',
'Location': url + redirectSuffix
});
res.end();
return true;
es.onmessage = function () {
closeFirstServer(function () {
_port = port;
createServer([], function (port, closeSecondServer) {
es.onopen = function () {
assert.equal(url + redirectSuffix, es.url);
es.close();
closeSecondServer(done);
};
}, function (req) {
assert.equal(redirectSuffix, req.url);
});
});
});
};
},
function (req, res) {
if (req.url != '/') return false;
res.writeHead(301, 'Moved Permanently', {
'Connection': 'Close',
'Location': url + redirectSuffix
});
res.end();
return true;
});
});
it('is attempted after http 307 redirect uses original url', function(done) {
var headers;
var url = 'http://localhost:' + _port;
var redirectSuffix = '/foobar';
createServer(['data: Hello\n\n'],
function(port, closeFirstServer) {
var es = new EventSource(url);
es.reconnectInterval = 0;
it('is attempted after http 307 redirect uses original url', function (done) {
var url = 'http://localhost:' + _port;
var redirectSuffix = '/foobar';
createServer(['data: Hello\n\n'],
function (port, closeFirstServer) {
var es = new EventSource(url);
es.reconnectInterval = 0;
es.onmessage = function(m) {
closeFirstServer(function() {
--_port;
createServer([], function(port, closeSecondServer) {
es.onopen = function() {
assert.equal(url, es.url);
es.close();
closeSecondServer(done);
};
}, function(req, res) { assert.equal('/', req.url); });
});
};
},
function(req, res) {
if (req.url != '/') return false;
res.writeHead(307, 'Temporary Redirect', {
'Connection': 'Close',
'Location': url + redirectSuffix
});
res.end();
return true;
es.onmessage = function (m) {
closeFirstServer(function () {
--_port;
createServer([], function (port, closeSecondServer) {
es.onopen = function () {
assert.equal(url, es.url);
es.close();
closeSecondServer(done);
};
}, function (req) {
assert.equal('/', req.url);
});
});
});
};
},
function (req, res) {
if (req.url != '/') return false;
res.writeHead(307, 'Temporary Redirect', {
'Connection': 'Close',
'Location': url + redirectSuffix
});
res.end();
return true;
});
});
});
describe('readyState', function() {
it('has CONNECTING constant', function(done) {
assert.equal(0, EventSource.CONNECTING);
done();
});
describe('readyState', function () {
it('has CONNECTING constant', function (done) {
assert.equal(0, EventSource.CONNECTING);
done();
});
it('has OPEN constant', function(done) {
assert.equal(1, EventSource.OPEN);
done();
});
it('has OPEN constant', function (done) {
assert.equal(1, EventSource.OPEN);
done();
});
it('has CLOSED constant', function(done) {
assert.equal(2, EventSource.CLOSED);
done();
});
it('has CLOSED constant', function (done) {
assert.equal(2, EventSource.CLOSED);
done();
});
it('is CONNECTING before connection has been established', function(done) {
createServer([], function(port, close) {
var es = new EventSource('http://localhost:' + port);
assert.equal(EventSource.CONNECTING, es.readyState);
es.onopen = function() {
es.close();
close(done);
}
});
it('is CONNECTING before connection has been established', function (done) {
createServer([], function (port, close) {
var es = new EventSource('http://localhost:' + port);
assert.equal(EventSource.CONNECTING, es.readyState);
es.onopen = function () {
es.close();
close(done);
}
});
});
it('is CONNECTING when server has closed the connection', function(done) {
createServer(["data: Hello\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
it('is CONNECTING when server has closed the connection', function (done) {
createServer(["data: Hello\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.reconnectInterval = 0;
es.onmessage = function(m) {
assert.equal("Hello", m.data);
close(function() {
setTimeout(function(){
assert.equal(EventSource.CONNECTING, es.readyState);
done();
}, 0);
});
};
es.onmessage = function (m) {
assert.equal("Hello", m.data);
close(function () {
setTimeout(function () {
assert.equal(EventSource.CONNECTING, es.readyState);
done();
}, 0);
});
};
});
});
it('is OPEN when connection has been established', function(done) {
createServer([], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onopen = function() {
assert.equal(EventSource.OPEN, es.readyState);
es.close();
close(done);
}
});
it('is OPEN when connection has been established', function (done) {
createServer([], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onopen = function () {
assert.equal(EventSource.OPEN, es.readyState);
es.close();
close(done);
}
});
});
it('is CLOSED after connection has been closed', function(done) {
createServer([], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onopen = function() {
es.close();
assert.equal(EventSource.CLOSED, es.readyState);
close(done);
};
});
it('is CLOSED after connection has been closed', function (done) {
createServer([], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onopen = function () {
es.close();
assert.equal(EventSource.CLOSED, es.readyState);
close(done);
};
});
});
});
describe('Properties', function() {
it('url exposes original request url', function(done) {
createServer([], function(port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url);
es.onopen = function() {
assert.equal(url, es.url);
es.close();
close(done);
}
});
describe('Properties', function () {
it('url exposes original request url', function (done) {
createServer([], function (port, close) {
var url = 'http://localhost:' + port;
var es = new EventSource(url);
es.onopen = function () {
assert.equal(url, es.url);
es.close();
close(done);
}
});
});
});
describe('Events', function() {
it('calls onopen when connection is established', function(done) {
createServer([], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onopen = function(event) {
assert.equal(event.type, 'open');
es.close();
close(done);
}
});
describe('Events', function () {
it('calls onopen when connection is established', function (done) {
createServer([], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onopen = function (event) {
assert.equal(event.type, 'open');
es.close();
close(done);
}
});
});
it('emits open event when connection is established', function(done) {
createServer([], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.addEventListener('open', function(event) {
assert.equal(event.type, 'open');
es.close();
close(done);
});
});
it('emits open event when connection is established', function (done) {
createServer([], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.addEventListener('open', function (event) {
assert.equal(event.type, 'open');
es.close();
close(done);
});
});
});
it('does not emit error when connection is closed by client', function(done) {
createServer([], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.addEventListener('open', function() {
es.close();
setTimeout(function() {
close(done);
}, 50);
});
es.addEventListener('error', function() {
throw new Error('error should not be emitted');
});
});
it('does not emit error when connection is closed by client', function (done) {
createServer([], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.addEventListener('open', function () {
es.close();
setTimeout(function () {
close(done);
}, 50);
});
es.addEventListener('error', function () {
throw new Error('error should not be emitted');
});
});
});
it('populates message\'s lastEventId correctly when the last event has an associated id', function(done) {
createServer(["id: 123\ndata: sample_data\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function(m) {
assert.equal(m.lastEventId, "123");
es.close();
close(done);
};
});
it('populates message\'s lastEventId correctly when the last event has an associated id', function (done) {
createServer(["id: 123\ndata: sample_data\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = function (m) {
assert.equal(m.lastEventId, "123");
es.close();
close(done);
};
});
it('populates message\'s lastEventId correctly when the last event doesn\'t have an associated id', function(done) {
createServer(["id: 123\ndata: Hello\n\n", "data: World\n\n"], function(port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
});
function first(m) {
es.onmessage = second;
}
it('populates message\'s lastEventId correctly when the last event doesn\'t have an associated id', function (done) {
createServer(["id: 123\ndata: Hello\n\n", "data: World\n\n"], function (port, close) {
var es = new EventSource('http://localhost:' + port);
es.onmessage = first;
function second(m) {
assert.equal(m.data, "World");
assert.equal(m.lastEventId, "123"); //expect to get back the previous event id
es.close();
close(done);
}
});
});
function first() {
es.onmessage = second;
}
function second(m) {
assert.equal(m.data, "World");
assert.equal(m.lastEventId, "123"); //expect to get back the previous event id
es.close();
close(done);
}
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc