mirror of
https://github.com/wassname/HackFlowy.git
synced 2026-07-16 01:20:31 +08:00
Initial work on the server
This commit is contained in:
+147
@@ -0,0 +1,147 @@
|
||||
// An experimental fake MySQL server for tricky integration tests. Expanded
|
||||
// as needed.
|
||||
|
||||
var Net = require('net');
|
||||
var Packets = require('../lib/protocol/packets');
|
||||
var PacketWriter = require('../lib/protocol/PacketWriter');
|
||||
var Parser = require('../lib/protocol/Parser');
|
||||
var Auth = require('../lib/protocol/Auth');
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var Util = require('util');
|
||||
|
||||
module.exports = FakeServer;
|
||||
Util.inherits(FakeServer, EventEmitter);
|
||||
function FakeServer(options) {
|
||||
EventEmitter.call(this);
|
||||
|
||||
this._server = null;
|
||||
this._connections = [];
|
||||
}
|
||||
|
||||
FakeServer.prototype.listen = function(port, cb) {
|
||||
this._server = Net.createServer(this._handleConnection.bind(this));
|
||||
this._server.listen(port, cb);
|
||||
};
|
||||
|
||||
FakeServer.prototype._handleConnection = function(socket) {
|
||||
var connection = new FakeConnection(socket);
|
||||
this.emit('connection', connection);
|
||||
this._connections.push(connection);
|
||||
};
|
||||
|
||||
FakeServer.prototype.destroy = function() {
|
||||
this._server.close();
|
||||
this._connections.forEach(function(connection) {
|
||||
connection.destroy();
|
||||
});
|
||||
};
|
||||
|
||||
Util.inherits(FakeConnection, EventEmitter);
|
||||
function FakeConnection(socket) {
|
||||
EventEmitter.call(this);
|
||||
|
||||
this._socket = socket;
|
||||
this._parser = new Parser({onPacket: this._parsePacket.bind(this)});
|
||||
|
||||
this._handshakeInitializationPacket = null;
|
||||
this._clientAuthenticationPacket = null;
|
||||
this._oldPasswordPacket = null;
|
||||
this._handshakeOptions = {};
|
||||
|
||||
socket.on('data', this._handleData.bind(this));
|
||||
}
|
||||
|
||||
FakeConnection.prototype.handshake = function(options) {
|
||||
this._handshakeOptions = options || {};
|
||||
|
||||
this._handshakeInitializationPacket = new Packets.HandshakeInitializationPacket({
|
||||
scrambleBuff1: new Buffer(8),
|
||||
scrambleBuff2: new Buffer(12),
|
||||
});
|
||||
|
||||
this._sendPacket(this._handshakeInitializationPacket);
|
||||
};
|
||||
|
||||
FakeConnection.prototype.deny = function(message, errno) {
|
||||
this._sendPacket(new Packets.ErrorPacket({
|
||||
message: message,
|
||||
errno: errno,
|
||||
}));
|
||||
};
|
||||
|
||||
FakeConnection.prototype._sendPacket = function(packet) {
|
||||
var writer = new PacketWriter();
|
||||
packet.write(writer);
|
||||
this._socket.write(writer.toBuffer(this._parser));
|
||||
};
|
||||
|
||||
FakeConnection.prototype._handleData = function(buffer) {
|
||||
this._parser.write(buffer);
|
||||
};
|
||||
|
||||
FakeConnection.prototype._parsePacket = function(header) {
|
||||
var Packet = this._determinePacket(header);
|
||||
var packet = new Packet();
|
||||
|
||||
packet.parse(this._parser);
|
||||
|
||||
switch (Packet) {
|
||||
case Packets.ClientAuthenticationPacket:
|
||||
this._clientAuthenticationPacket = packet;
|
||||
|
||||
if (this._handshakeOptions.oldPassword) {
|
||||
this._sendPacket(new Packets.UseOldPasswordPacket());
|
||||
} else {
|
||||
if (this._handshakeOptions.user || this._handshakeOptions.password) {
|
||||
throw new Error('not implemented');
|
||||
}
|
||||
|
||||
this._sendPacket(new Packets.OkPacket());
|
||||
this._parser.resetPacketNumber();
|
||||
}
|
||||
break;
|
||||
case Packets.OldPasswordPacket:
|
||||
this._oldPasswordPacket = packet;
|
||||
|
||||
var expected = Auth.scramble323(this._handshakeInitializationPacket.scrambleBuff(), this._handshakeOptions.password);
|
||||
var got = packet.scrambleBuff;
|
||||
|
||||
var toString = function(buffer) {
|
||||
return Array.prototype.slice.call(buffer).join(',');
|
||||
};
|
||||
|
||||
if (toString(expected) === toString(got)) {
|
||||
this._sendPacket(new Packets.OkPacket());
|
||||
} else {
|
||||
this._sendPacket(new Packets.ErrorPacket());
|
||||
}
|
||||
|
||||
this._parser.resetPacketNumber();
|
||||
break;
|
||||
case Packets.ComQueryPacket:
|
||||
this.emit('query', packet);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unexpected packet: ' + Packet.name)
|
||||
}
|
||||
};
|
||||
|
||||
FakeConnection.prototype._determinePacket = function() {
|
||||
if (!this._clientAuthenticationPacket) {
|
||||
return Packets.ClientAuthenticationPacket;
|
||||
} else if (this._handshakeOptions.oldPassword && !this._oldPasswordPacket) {
|
||||
return Packets.OldPasswordPacket;
|
||||
}
|
||||
|
||||
var firstByte = this._parser.peak();
|
||||
switch (firstByte) {
|
||||
case 0x03: return Packets.ComQueryPacket;
|
||||
default:
|
||||
throw new Error('Unknown packet, first byte: ' + firstByte);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
FakeConnection.prototype.destroy = function() {
|
||||
this._socket.destroy();
|
||||
};
|
||||
Reference in New Issue
Block a user