diff --git a/lib/eventsource.js b/lib/eventsource.js index a7bb4789..a2d7fa7f 100644 --- a/lib/eventsource.js +++ b/lib/eventsource.js @@ -174,6 +174,8 @@ function EventSource (url, eventSourceInitDict) { // Source/WebCore/page/EventSource.cpp var isFirst = true var buf + var startingPos = 0 + var startingFieldLength = -1 res.on('data', function (chunk) { buf = buf ? Buffer.concat([buf, chunk]) : chunk if (isFirst && hasBom(buf)) { @@ -193,10 +195,10 @@ function EventSource (url, eventSourceInitDict) { } var lineLength = -1 - var fieldLength = -1 + var fieldLength = startingFieldLength var c - for (var i = pos; lineLength < 0 && i < length; ++i) { + for (var i = startingPos; lineLength < 0 && i < length; ++i) { c = buf[i] if (c === colon) { if (fieldLength < 0) { @@ -211,7 +213,12 @@ function EventSource (url, eventSourceInitDict) { } if (lineLength < 0) { + startingPos = length - pos + startingFieldLength = fieldLength break + } else { + startingPos = 0 + startingFieldLength = -1 } parseEventStreamLine(buf, pos, fieldLength, lineLength) diff --git a/test/eventsource_test.js b/test/eventsource_test.js index a547b32b..6e789391 100644 --- a/test/eventsource_test.js +++ b/test/eventsource_test.js @@ -466,6 +466,24 @@ describe('Parser', function () { } }) }) + + it('parses a relatively huge message across many chunks efficiently', function (done) { + this.timeout(1000) + + createServer(function (err, server) { + if (err) return done(err) + + var longMessage = 'data: ' + new Array(100000).join('a') + '\n\n' + var longMessageChunks = longMessage.match(/.{1,10}/gs); + server.on('request', writeEvents(longMessageChunks)) + + var es = new EventSource(server.url) + + es.onmessage = function () { + server.close(done) + } + }) + }) }) describe('HTTP Request', function () {