-
Notifications
You must be signed in to change notification settings - Fork 446
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
馃攰 Warn when messages are sent before the v1.1 handshake
At the moment, it's possible for messages to be sent before the client- server handshake. Sending messages before the handshake has happened has undefined behaviour, and can result in errors such as in: #605 We can't just ignore these messages, because old clients might potentially be on v1.0 of the client-server protocol, in which the server informs the client when it's ready, but not the other way around, so it's impossible to know when a client should be considered "ready", and its messages acceptable. Instead, we add a warning for clients on v1.1 who have sent a message before their handshake. In order to aid with debugging, we keep track of the first message received, and log it when the handshake is received (which means that v1.0 clients will never get such a warning).
- Loading branch information
1 parent
c1f1474
commit 6ee645d
Showing
4 changed files
with
100 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
var Backend = require('../lib/backend'); | ||
var logger = require('../lib/logger'); | ||
var sinon = require('sinon'); | ||
var StreamSocket = require('../lib/stream-socket'); | ||
var expect = require('chai').expect; | ||
var ACTIONS = require('../lib/message-actions').ACTIONS; | ||
var Connection = require('../lib/client/connection'); | ||
var LegacyConnection = require('sharedb-legacy/lib/client').Connection; | ||
|
||
describe('Agent', function() { | ||
var backend; | ||
|
||
beforeEach(function() { | ||
backend = new Backend(); | ||
}); | ||
|
||
afterEach(function(done) { | ||
backend.close(done); | ||
}); | ||
|
||
describe('handshake', function() { | ||
it('warns when messages are sent before the handshake', function(done) { | ||
var socket = new StreamSocket(); | ||
var stream = socket.stream; | ||
backend.listen(stream); | ||
sinon.spy(logger, 'warn'); | ||
socket.send(JSON.stringify({a: ACTIONS.subscribe, c: 'dogs', d: 'fido'})); | ||
var connection = new Connection(socket); | ||
socket._open(); | ||
connection.once('connected', function() { | ||
expect(logger.warn).to.have.been.calledOnceWithExactly( | ||
'Unexpected message received before handshake', | ||
{a: ACTIONS.subscribe, c: 'dogs', d: 'fido'} | ||
); | ||
done(); | ||
}); | ||
}); | ||
|
||
it('does not warn when messages are sent after the handshake', function(done) { | ||
var socket = new StreamSocket(); | ||
var stream = socket.stream; | ||
var agent = backend.listen(stream); | ||
sinon.spy(logger, 'warn'); | ||
var connection = new Connection(socket); | ||
socket._open(); | ||
connection.once('connected', function() { | ||
socket.send(JSON.stringify({a: ACTIONS.subscribe, c: 'dogs', d: 'fido'})); | ||
expect(logger.warn).not.to.have.been.called; | ||
expect(agent._firstReceivedMessage).to.be.null; | ||
done(); | ||
}); | ||
}); | ||
|
||
it('does not warn for clients on protocol v1.0', function(done) { | ||
backend.use('receive', function(request, next) { | ||
var error = null; | ||
if (request.data.a === ACTIONS.handshake) error = new Error('Unexpected handshake'); | ||
next(error); | ||
}); | ||
var socket = new StreamSocket(); | ||
var stream = socket.stream; | ||
backend.listen(stream); | ||
sinon.spy(logger, 'warn'); | ||
socket.send(JSON.stringify({a: ACTIONS.subscribe, c: 'dogs', d: 'fido'})); | ||
var connection = new LegacyConnection(socket); | ||
socket._open(); | ||
connection.get('dogs', 'fido').fetch(function(error) { | ||
if (error) return done(error); | ||
expect(logger.warn).not.to.have.been.called; | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters