Update bot
Took 2 hours 17 minutes
This commit is contained in:
91
node_modules/mysql2/lib/commands/auth_switch.js
generated
vendored
Normal file
91
node_modules/mysql2/lib/commands/auth_switch.js
generated
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
'use strict';
|
||||
|
||||
const Packets = require('../packets/index.js');
|
||||
const sha256_password = require('../auth_plugins/sha256_password');
|
||||
const caching_sha2_password = require('../auth_plugins/caching_sha2_password.js');
|
||||
const mysql_native_password = require('../auth_plugins/mysql_native_password.js');
|
||||
|
||||
const standardAuthPlugins = {
|
||||
sha256_password: sha256_password({}),
|
||||
caching_sha2_password: caching_sha2_password({}),
|
||||
mysql_native_password: mysql_native_password({})
|
||||
};
|
||||
|
||||
function warnLegacyAuthSwitch() {
|
||||
console.warn(
|
||||
'WARNING! authSwitchHandler api is deprecated, please use new authPlugins api'
|
||||
);
|
||||
}
|
||||
|
||||
function authSwitchRequest(packet, connection, command) {
|
||||
const { pluginName, pluginData } = Packets.AuthSwitchRequest.fromPacket(
|
||||
packet
|
||||
);
|
||||
let authPlugin =
|
||||
connection.config.authPlugins && connection.config.authPlugins[pluginName];
|
||||
|
||||
// legacy plugin api don't allow to override mysql_native_password
|
||||
// if pluginName is mysql_native_password it's using standard auth4.1 auth
|
||||
if (
|
||||
connection.config.authSwitchHandler &&
|
||||
pluginName !== 'mysql_native_password'
|
||||
) {
|
||||
const legacySwitchHandler = connection.config.authSwitchHandler;
|
||||
warnLegacyAuthSwitch();
|
||||
legacySwitchHandler({ pluginName, pluginData }, (err, data) => {
|
||||
if (err) {
|
||||
connection.emit('error', err);
|
||||
return;
|
||||
}
|
||||
connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!authPlugin) {
|
||||
authPlugin = standardAuthPlugins[pluginName];
|
||||
}
|
||||
if (!authPlugin) {
|
||||
throw new Error(
|
||||
`Server requests authentication using unknown plugin ${pluginName}. See ${'TODO: add plugins doco here'} on how to configure or author authentication plugins.`
|
||||
);
|
||||
}
|
||||
connection._authPlugin = authPlugin({ connection, command });
|
||||
Promise.resolve(connection._authPlugin(pluginData)).then(data => {
|
||||
if (data) {
|
||||
connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function authSwitchRequestMoreData(packet, connection) {
|
||||
const { data } = Packets.AuthSwitchRequestMoreData.fromPacket(packet);
|
||||
|
||||
if (connection.config.authSwitchHandler) {
|
||||
const legacySwitchHandler = connection.config.authSwitchHandler;
|
||||
warnLegacyAuthSwitch();
|
||||
legacySwitchHandler({ pluginData: data }, (err, data) => {
|
||||
if (err) {
|
||||
connection.emit('error', err);
|
||||
return;
|
||||
}
|
||||
connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!connection._authPlugin) {
|
||||
throw new Error(
|
||||
'AuthPluginMoreData received but no auth plugin instance found'
|
||||
);
|
||||
}
|
||||
Promise.resolve(connection._authPlugin(data)).then(data => {
|
||||
if (data) {
|
||||
connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
authSwitchRequest,
|
||||
authSwitchRequestMoreData
|
||||
};
|
109
node_modules/mysql2/lib/commands/binlog_dump.js
generated
vendored
Normal file
109
node_modules/mysql2/lib/commands/binlog_dump.js
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
'use strict';
|
||||
|
||||
const Command = require('./command');
|
||||
const Packets = require('../packets');
|
||||
|
||||
const eventParsers = [];
|
||||
|
||||
class BinlogEventHeader {
|
||||
constructor(packet) {
|
||||
this.timestamp = packet.readInt32();
|
||||
this.eventType = packet.readInt8();
|
||||
this.serverId = packet.readInt32();
|
||||
this.eventSize = packet.readInt32();
|
||||
this.logPos = packet.readInt32();
|
||||
this.flags = packet.readInt16();
|
||||
}
|
||||
}
|
||||
|
||||
class BinlogDump extends Command {
|
||||
constructor(opts) {
|
||||
super();
|
||||
// this.onResult = callback;
|
||||
this.opts = opts;
|
||||
}
|
||||
|
||||
start(packet, connection) {
|
||||
const newPacket = new Packets.BinlogDump(this.opts);
|
||||
connection.writePacket(newPacket.toPacket(1));
|
||||
return BinlogDump.prototype.binlogData;
|
||||
}
|
||||
|
||||
binlogData(packet) {
|
||||
// ok - continue consuming events
|
||||
// error - error
|
||||
// eof - end of binlog
|
||||
if (packet.isEOF()) {
|
||||
this.emit('eof');
|
||||
return null;
|
||||
}
|
||||
// binlog event header
|
||||
packet.readInt8();
|
||||
const header = new BinlogEventHeader(packet);
|
||||
const EventParser = eventParsers[header.eventType];
|
||||
let event;
|
||||
if (EventParser) {
|
||||
event = new EventParser(packet);
|
||||
} else {
|
||||
event = {
|
||||
name: 'UNKNOWN'
|
||||
};
|
||||
}
|
||||
event.header = header;
|
||||
this.emit('event', event);
|
||||
return BinlogDump.prototype.binlogData;
|
||||
}
|
||||
}
|
||||
|
||||
class RotateEvent {
|
||||
constructor(packet) {
|
||||
this.pposition = packet.readInt32();
|
||||
// TODO: read uint64 here
|
||||
packet.readInt32(); // positionDword2
|
||||
this.nextBinlog = packet.readString();
|
||||
this.name = 'RotateEvent';
|
||||
}
|
||||
}
|
||||
|
||||
class FormatDescriptionEvent {
|
||||
constructor(packet) {
|
||||
this.binlogVersion = packet.readInt16();
|
||||
this.serverVersion = packet.readString(50).replace(/\u0000.*/, ''); // eslint-disable-line no-control-regex
|
||||
this.createTimestamp = packet.readInt32();
|
||||
this.eventHeaderLength = packet.readInt8(); // should be 19
|
||||
this.eventsLength = packet.readBuffer();
|
||||
this.name = 'FormatDescriptionEvent';
|
||||
}
|
||||
}
|
||||
|
||||
class QueryEvent {
|
||||
constructor(packet) {
|
||||
const parseStatusVars = require('../packets/binlog_query_statusvars.js');
|
||||
this.slaveProxyId = packet.readInt32();
|
||||
this.executionTime = packet.readInt32();
|
||||
const schemaLength = packet.readInt8();
|
||||
this.errorCode = packet.readInt16();
|
||||
const statusVarsLength = packet.readInt16();
|
||||
const statusVars = packet.readBuffer(statusVarsLength);
|
||||
this.schema = packet.readString(schemaLength);
|
||||
packet.readInt8(); // should be zero
|
||||
this.statusVars = parseStatusVars(statusVars);
|
||||
this.query = packet.readString();
|
||||
this.name = 'QueryEvent';
|
||||
}
|
||||
}
|
||||
|
||||
class XidEvent {
|
||||
constructor(packet) {
|
||||
this.binlogVersion = packet.readInt16();
|
||||
this.xid = packet.readInt64();
|
||||
this.name = 'XidEvent';
|
||||
}
|
||||
}
|
||||
|
||||
eventParsers[2] = QueryEvent;
|
||||
eventParsers[4] = RotateEvent;
|
||||
eventParsers[15] = FormatDescriptionEvent;
|
||||
eventParsers[16] = XidEvent;
|
||||
|
||||
module.exports = BinlogDump;
|
47
node_modules/mysql2/lib/commands/change_user.js
generated
vendored
Normal file
47
node_modules/mysql2/lib/commands/change_user.js
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
'use strict';
|
||||
|
||||
const Command = require('./command.js');
|
||||
const Packets = require('../packets/index.js');
|
||||
const ClientHandshake = require('./client_handshake.js');
|
||||
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
||||
|
||||
class ChangeUser extends Command {
|
||||
constructor(options, callback) {
|
||||
super();
|
||||
this.onResult = callback;
|
||||
this.user = options.user;
|
||||
this.password = options.password;
|
||||
this.database = options.database;
|
||||
this.passwordSha1 = options.passwordSha1;
|
||||
this.charsetNumber = options.charsetNumber;
|
||||
this.currentConfig = options.currentConfig;
|
||||
}
|
||||
start(packet, connection) {
|
||||
const newPacket = new Packets.ChangeUser({
|
||||
flags: connection.config.clientFlags,
|
||||
user: this.user,
|
||||
database: this.database,
|
||||
charsetNumber: this.charsetNumber,
|
||||
password: this.password,
|
||||
passwordSha1: this.passwordSha1,
|
||||
authPluginData1: connection._handshakePacket.authPluginData1,
|
||||
authPluginData2: connection._handshakePacket.authPluginData2
|
||||
});
|
||||
this.currentConfig.user = this.user;
|
||||
this.currentConfig.password = this.password;
|
||||
this.currentConfig.database = this.database;
|
||||
this.currentConfig.charsetNumber = this.charsetNumber;
|
||||
connection.clientEncoding = CharsetToEncoding[this.charsetNumber];
|
||||
// reset prepared statements cache as all statements become invalid after changeUser
|
||||
connection._statements.reset();
|
||||
connection.writePacket(newPacket.toPacket());
|
||||
return ChangeUser.prototype.handshakeResult;
|
||||
}
|
||||
}
|
||||
|
||||
ChangeUser.prototype.handshakeResult =
|
||||
ClientHandshake.prototype.handshakeResult;
|
||||
ChangeUser.prototype.calculateNativePasswordAuthToken =
|
||||
ClientHandshake.prototype.calculateNativePasswordAuthToken;
|
||||
|
||||
module.exports = ChangeUser;
|
187
node_modules/mysql2/lib/commands/client_handshake.js
generated
vendored
Normal file
187
node_modules/mysql2/lib/commands/client_handshake.js
generated
vendored
Normal file
@ -0,0 +1,187 @@
|
||||
'use strict';
|
||||
|
||||
const Command = require('./command.js');
|
||||
const Packets = require('../packets/index.js');
|
||||
const ClientConstants = require('../constants/client.js');
|
||||
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
||||
const auth41 = require('../auth_41.js');
|
||||
|
||||
function flagNames(flags) {
|
||||
const res = [];
|
||||
for (const c in ClientConstants) {
|
||||
if (flags & ClientConstants[c]) {
|
||||
res.push(c.replace(/_/g, ' ').toLowerCase());
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
class ClientHandshake extends Command {
|
||||
constructor(clientFlags) {
|
||||
super();
|
||||
this.handshake = null;
|
||||
this.clientFlags = clientFlags;
|
||||
}
|
||||
|
||||
start() {
|
||||
return ClientHandshake.prototype.handshakeInit;
|
||||
}
|
||||
|
||||
sendSSLRequest(connection) {
|
||||
const sslRequest = new Packets.SSLRequest(
|
||||
this.clientFlags,
|
||||
connection.config.charsetNumber
|
||||
);
|
||||
connection.writePacket(sslRequest.toPacket());
|
||||
}
|
||||
|
||||
sendCredentials(connection) {
|
||||
if (connection.config.debug) {
|
||||
// eslint-disable-next-line
|
||||
console.log(
|
||||
'Sending handshake packet: flags:%d=(%s)',
|
||||
this.clientFlags,
|
||||
flagNames(this.clientFlags).join(', ')
|
||||
);
|
||||
}
|
||||
this.user = connection.config.user;
|
||||
this.password = connection.config.password;
|
||||
this.passwordSha1 = connection.config.passwordSha1;
|
||||
this.database = connection.config.database;
|
||||
this.autPluginName = this.handshake.autPluginName;
|
||||
const handshakeResponse = new Packets.HandshakeResponse({
|
||||
flags: this.clientFlags,
|
||||
user: this.user,
|
||||
database: this.database,
|
||||
password: this.password,
|
||||
passwordSha1: this.passwordSha1,
|
||||
charsetNumber: connection.config.charsetNumber,
|
||||
authPluginData1: this.handshake.authPluginData1,
|
||||
authPluginData2: this.handshake.authPluginData2,
|
||||
compress: connection.config.compress,
|
||||
connectAttributes: connection.config.connectAttributes
|
||||
});
|
||||
connection.writePacket(handshakeResponse.toPacket());
|
||||
}
|
||||
|
||||
calculateNativePasswordAuthToken(authPluginData) {
|
||||
// TODO: dont split into authPluginData1 and authPluginData2, instead join when 1 & 2 received
|
||||
const authPluginData1 = authPluginData.slice(0, 8);
|
||||
const authPluginData2 = authPluginData.slice(8, 20);
|
||||
let authToken;
|
||||
if (this.passwordSha1) {
|
||||
authToken = auth41.calculateTokenFromPasswordSha(
|
||||
this.passwordSha1,
|
||||
authPluginData1,
|
||||
authPluginData2
|
||||
);
|
||||
} else {
|
||||
authToken = auth41.calculateToken(
|
||||
this.password,
|
||||
authPluginData1,
|
||||
authPluginData2
|
||||
);
|
||||
}
|
||||
return authToken;
|
||||
}
|
||||
|
||||
handshakeInit(helloPacket, connection) {
|
||||
this.on('error', e => {
|
||||
connection._fatalError = e;
|
||||
connection._protocolError = e;
|
||||
});
|
||||
this.handshake = Packets.Handshake.fromPacket(helloPacket);
|
||||
if (connection.config.debug) {
|
||||
// eslint-disable-next-line
|
||||
console.log(
|
||||
'Server hello packet: capability flags:%d=(%s)',
|
||||
this.handshake.capabilityFlags,
|
||||
flagNames(this.handshake.capabilityFlags).join(', ')
|
||||
);
|
||||
}
|
||||
connection.serverCapabilityFlags = this.handshake.capabilityFlags;
|
||||
connection.serverEncoding = CharsetToEncoding[this.handshake.characterSet];
|
||||
connection.connectionId = this.handshake.connectionId;
|
||||
const serverSSLSupport =
|
||||
this.handshake.capabilityFlags & ClientConstants.SSL;
|
||||
// use compression only if requested by client and supported by server
|
||||
connection.config.compress =
|
||||
connection.config.compress &&
|
||||
this.handshake.capabilityFlags & ClientConstants.COMPRESS;
|
||||
this.clientFlags = this.clientFlags | connection.config.compress;
|
||||
if (connection.config.ssl) {
|
||||
// client requires SSL but server does not support it
|
||||
if (!serverSSLSupport) {
|
||||
const err = new Error('Server does not support secure connnection');
|
||||
err.code = 'HANDSHAKE_NO_SSL_SUPPORT';
|
||||
err.fatal = true;
|
||||
this.emit('error', err);
|
||||
return false;
|
||||
}
|
||||
// send ssl upgrade request and immediately upgrade connection to secure
|
||||
this.clientFlags |= ClientConstants.SSL;
|
||||
this.sendSSLRequest(connection);
|
||||
connection.startTLS(err => {
|
||||
// after connection is secure
|
||||
if (err) {
|
||||
// SSL negotiation error are fatal
|
||||
err.code = 'HANDSHAKE_SSL_ERROR';
|
||||
err.fatal = true;
|
||||
this.emit('error', err);
|
||||
return;
|
||||
}
|
||||
// rest of communication is encrypted
|
||||
this.sendCredentials(connection);
|
||||
});
|
||||
} else {
|
||||
this.sendCredentials(connection);
|
||||
}
|
||||
return ClientHandshake.prototype.handshakeResult;
|
||||
}
|
||||
|
||||
handshakeResult(packet, connection) {
|
||||
const marker = packet.peekByte();
|
||||
if (marker === 0xfe || marker === 1) {
|
||||
const authSwitch = require('./auth_switch');
|
||||
try {
|
||||
if (marker === 1) {
|
||||
authSwitch.authSwitchRequestMoreData(packet, connection, this);
|
||||
} else {
|
||||
authSwitch.authSwitchRequest(packet, connection, this);
|
||||
}
|
||||
return ClientHandshake.prototype.handshakeResult;
|
||||
} catch (err) {
|
||||
if (this.onResult) {
|
||||
this.onResult(err);
|
||||
} else {
|
||||
connection.emit('error', err);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (marker !== 0) {
|
||||
const err = new Error('Unexpected packet during handshake phase');
|
||||
if (this.onResult) {
|
||||
this.onResult(err);
|
||||
} else {
|
||||
connection.emit('error', err);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// this should be called from ClientHandshake command only
|
||||
// and skipped when called from ChangeUser command
|
||||
if (!connection.authorized) {
|
||||
connection.authorized = true;
|
||||
if (connection.config.compress) {
|
||||
const enableCompression = require('../compressed_protocol.js')
|
||||
.enableCompression;
|
||||
enableCompression(connection);
|
||||
}
|
||||
}
|
||||
if (this.onResult) {
|
||||
this.onResult(null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
module.exports = ClientHandshake;
|
18
node_modules/mysql2/lib/commands/close_statement.js
generated
vendored
Normal file
18
node_modules/mysql2/lib/commands/close_statement.js
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
const Command = require('./command');
|
||||
const Packets = require('../packets/index.js');
|
||||
|
||||
class CloseStatement extends Command {
|
||||
constructor(id) {
|
||||
super();
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
start(packet, connection) {
|
||||
connection.writePacket(new Packets.CloseStatement(this.id).toPacket(1));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CloseStatement;
|
49
node_modules/mysql2/lib/commands/command.js
generated
vendored
Normal file
49
node_modules/mysql2/lib/commands/command.js
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
'use strict';
|
||||
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
|
||||
class Command extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
this.next = null;
|
||||
}
|
||||
|
||||
// slow. debug only
|
||||
stateName() {
|
||||
const state = this.next;
|
||||
for (const i in this) {
|
||||
if (this[i] === state && i !== 'next') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 'unknown name';
|
||||
}
|
||||
|
||||
execute(packet, connection) {
|
||||
if (!this.next) {
|
||||
this.next = this.start;
|
||||
connection._resetSequenceId();
|
||||
}
|
||||
if (packet && packet.isError()) {
|
||||
const err = packet.asError(connection.clientEncoding);
|
||||
if (this.onResult) {
|
||||
this.onResult(err);
|
||||
this.emit('end');
|
||||
} else {
|
||||
this.emit('error', err);
|
||||
this.emit('end');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// TODO: don't return anything from execute, it's ugly and error-prone. Listen for 'end' event in connection
|
||||
this.next = this.next(packet, connection);
|
||||
if (this.next) {
|
||||
return false;
|
||||
}
|
||||
this.emit('end');
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Command;
|
102
node_modules/mysql2/lib/commands/execute.js
generated
vendored
Normal file
102
node_modules/mysql2/lib/commands/execute.js
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
'use strict';
|
||||
|
||||
const Command = require('./command.js');
|
||||
const Query = require('./query.js');
|
||||
const Packets = require('../packets/index.js');
|
||||
|
||||
const getBinaryParser = require('../parsers/binary_parser.js');
|
||||
|
||||
class Execute extends Command {
|
||||
constructor(options, callback) {
|
||||
super();
|
||||
this.statement = options.statement;
|
||||
this.sql = options.sql;
|
||||
this.values = options.values;
|
||||
this.onResult = callback;
|
||||
this.parameters = options.values;
|
||||
this.insertId = 0;
|
||||
this._rows = [];
|
||||
this._fields = [];
|
||||
this._result = [];
|
||||
this._fieldCount = 0;
|
||||
this._rowParser = null;
|
||||
this._executeOptions = options;
|
||||
this._resultIndex = 0;
|
||||
this._localStream = null;
|
||||
this._unpipeStream = function() {};
|
||||
this._streamFactory = options.infileStreamFactory;
|
||||
this._connection = null;
|
||||
}
|
||||
|
||||
buildParserFromFields(fields, connection) {
|
||||
return getBinaryParser(fields, this.options, connection.config);
|
||||
}
|
||||
|
||||
start(packet, connection) {
|
||||
this._connection = connection;
|
||||
this.options = Object.assign({}, connection.config, this._executeOptions);
|
||||
const executePacket = new Packets.Execute(
|
||||
this.statement.id,
|
||||
this.parameters,
|
||||
connection.config.charsetNumber,
|
||||
connection.config.timezone
|
||||
);
|
||||
//For reasons why this try-catch is here, please see
|
||||
// https://github.com/sidorares/node-mysql2/pull/689
|
||||
//For additional discussion, see
|
||||
// 1. https://github.com/sidorares/node-mysql2/issues/493
|
||||
// 2. https://github.com/sidorares/node-mysql2/issues/187
|
||||
// 3. https://github.com/sidorares/node-mysql2/issues/480
|
||||
try {
|
||||
connection.writePacket(executePacket.toPacket(1));
|
||||
} catch (error) {
|
||||
this.onResult(error);
|
||||
}
|
||||
return Execute.prototype.resultsetHeader;
|
||||
}
|
||||
|
||||
readField(packet, connection) {
|
||||
let fields;
|
||||
// disabling for now, but would be great to find reliable way to parse fields only once
|
||||
// fields reported by prepare can be empty at all or just incorrect - see #169
|
||||
//
|
||||
// perfomance optimisation: if we already have this field parsed in statement header, use one from header
|
||||
// const field = this.statement.columns.length == this._fieldCount ?
|
||||
// this.statement.columns[this._receivedFieldsCount] : new Packets.ColumnDefinition(packet);
|
||||
const field = new Packets.ColumnDefinition(
|
||||
packet,
|
||||
connection.clientEncoding
|
||||
);
|
||||
this._receivedFieldsCount++;
|
||||
this._fields[this._resultIndex].push(field);
|
||||
if (this._receivedFieldsCount === this._fieldCount) {
|
||||
fields = this._fields[this._resultIndex];
|
||||
this.emit('fields', fields, this._resultIndex);
|
||||
return Execute.prototype.fieldsEOF;
|
||||
}
|
||||
return Execute.prototype.readField;
|
||||
}
|
||||
|
||||
fieldsEOF(packet, connection) {
|
||||
// check EOF
|
||||
if (!packet.isEOF()) {
|
||||
return connection.protocolError('Expected EOF packet');
|
||||
}
|
||||
this._rowParser = this.buildParserFromFields(
|
||||
this._fields[this._resultIndex],
|
||||
connection
|
||||
);
|
||||
return Execute.prototype.row;
|
||||
}
|
||||
}
|
||||
|
||||
Execute.prototype.done = Query.prototype.done;
|
||||
Execute.prototype.doneInsert = Query.prototype.doneInsert;
|
||||
Execute.prototype.resultsetHeader = Query.prototype.resultsetHeader;
|
||||
Execute.prototype._findOrCreateReadStream =
|
||||
Query.prototype._findOrCreateReadStream;
|
||||
Execute.prototype._streamLocalInfile = Query.prototype._streamLocalInfile;
|
||||
Execute.prototype.row = Query.prototype.row;
|
||||
Execute.prototype.stream = Query.prototype.stream;
|
||||
|
||||
module.exports = Execute;
|
27
node_modules/mysql2/lib/commands/index.js
generated
vendored
Normal file
27
node_modules/mysql2/lib/commands/index.js
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
const ClientHandshake = require('./client_handshake.js');
|
||||
const ServerHandshake = require('./server_handshake.js');
|
||||
const Query = require('./query.js');
|
||||
const Prepare = require('./prepare.js');
|
||||
const CloseStatement = require('./close_statement.js');
|
||||
const Execute = require('./execute.js');
|
||||
const Ping = require('./ping.js');
|
||||
const RegisterSlave = require('./register_slave.js');
|
||||
const BinlogDump = require('./binlog_dump.js');
|
||||
const ChangeUser = require('./change_user.js');
|
||||
const Quit = require('./quit.js');
|
||||
|
||||
module.exports = {
|
||||
ClientHandshake,
|
||||
ServerHandshake,
|
||||
Query,
|
||||
Prepare,
|
||||
CloseStatement,
|
||||
Execute,
|
||||
Ping,
|
||||
RegisterSlave,
|
||||
BinlogDump,
|
||||
ChangeUser,
|
||||
Quit
|
||||
};
|
36
node_modules/mysql2/lib/commands/ping.js
generated
vendored
Normal file
36
node_modules/mysql2/lib/commands/ping.js
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
'use strict';
|
||||
|
||||
const Command = require('./command');
|
||||
const CommandCode = require('../constants/commands');
|
||||
const Packet = require('../packets/packet');
|
||||
|
||||
// TODO: time statistics?
|
||||
// usefull for queue size and network latency monitoring
|
||||
// store created,sent,reply timestamps
|
||||
class Ping extends Command {
|
||||
constructor(callback) {
|
||||
super();
|
||||
this.onResult = callback;
|
||||
}
|
||||
|
||||
start(packet, connection) {
|
||||
const ping = new Packet(
|
||||
0,
|
||||
Buffer.from([1, 0, 0, 0, CommandCode.PING]),
|
||||
0,
|
||||
5
|
||||
);
|
||||
connection.writePacket(ping);
|
||||
return Ping.prototype.pingResponse;
|
||||
}
|
||||
|
||||
pingResponse() {
|
||||
// TODO: check it's OK packet. error check already done in caller
|
||||
if (this.onResult) {
|
||||
process.nextTick(this.onResult.bind(this));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Ping;
|
130
node_modules/mysql2/lib/commands/prepare.js
generated
vendored
Normal file
130
node_modules/mysql2/lib/commands/prepare.js
generated
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
'use strict';
|
||||
|
||||
const Packets = require('../packets/index.js');
|
||||
const Command = require('./command.js');
|
||||
const CloseStatement = require('./close_statement.js');
|
||||
const Execute = require('./execute.js');
|
||||
|
||||
class PreparedStatementInfo {
|
||||
constructor(query, id, columns, parameters, connection) {
|
||||
this.query = query;
|
||||
this.id = id;
|
||||
this.columns = columns;
|
||||
this.parameters = parameters;
|
||||
this.rowParser = null;
|
||||
this._connection = connection;
|
||||
}
|
||||
|
||||
close() {
|
||||
return this._connection.addCommand(new CloseStatement(this.id));
|
||||
}
|
||||
|
||||
execute(parameters, callback) {
|
||||
if (typeof parameters === 'function') {
|
||||
callback = parameters;
|
||||
parameters = [];
|
||||
}
|
||||
return this._connection.addCommand(
|
||||
new Execute({ statement: this, values: parameters }, callback)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class Prepare extends Command {
|
||||
constructor(options, callback) {
|
||||
super();
|
||||
this.query = options.sql;
|
||||
this.onResult = callback;
|
||||
this.id = 0;
|
||||
this.fieldCount = 0;
|
||||
this.parameterCount = 0;
|
||||
this.fields = [];
|
||||
this.parameterDefinitions = [];
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
start(packet, connection) {
|
||||
const Connection = connection.constructor;
|
||||
this.key = Connection.statementKey(this.options);
|
||||
const statement = connection._statements.get(this.key);
|
||||
if (statement) {
|
||||
if (this.onResult) {
|
||||
this.onResult(null, statement);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const cmdPacket = new Packets.PrepareStatement(
|
||||
this.query,
|
||||
connection.config.charsetNumber
|
||||
);
|
||||
connection.writePacket(cmdPacket.toPacket(1));
|
||||
return Prepare.prototype.prepareHeader;
|
||||
}
|
||||
|
||||
prepareHeader(packet, connection) {
|
||||
const header = new Packets.PreparedStatementHeader(packet);
|
||||
this.id = header.id;
|
||||
this.fieldCount = header.fieldCount;
|
||||
this.parameterCount = header.parameterCount;
|
||||
if (this.parameterCount > 0) {
|
||||
return Prepare.prototype.readParameter;
|
||||
} if (this.fieldCount > 0) {
|
||||
return Prepare.prototype.readField;
|
||||
}
|
||||
return this.prepareDone(connection);
|
||||
|
||||
}
|
||||
|
||||
readParameter(packet, connection) {
|
||||
const def = new Packets.ColumnDefinition(packet, connection.clientEncoding);
|
||||
this.parameterDefinitions.push(def);
|
||||
if (this.parameterDefinitions.length === this.parameterCount) {
|
||||
return Prepare.prototype.parametersEOF;
|
||||
}
|
||||
return this.readParameter;
|
||||
}
|
||||
|
||||
readField(packet, connection) {
|
||||
const def = new Packets.ColumnDefinition(packet, connection.clientEncoding);
|
||||
this.fields.push(def);
|
||||
if (this.fields.length === this.fieldCount) {
|
||||
return Prepare.prototype.fieldsEOF;
|
||||
}
|
||||
return Prepare.prototype.readField;
|
||||
}
|
||||
|
||||
parametersEOF(packet, connection) {
|
||||
if (!packet.isEOF()) {
|
||||
return connection.protocolError('Expected EOF packet after parameters');
|
||||
}
|
||||
if (this.fieldCount > 0) {
|
||||
return Prepare.prototype.readField;
|
||||
}
|
||||
return this.prepareDone(connection);
|
||||
|
||||
}
|
||||
|
||||
fieldsEOF(packet, connection) {
|
||||
if (!packet.isEOF()) {
|
||||
return connection.protocolError('Expected EOF packet after fields');
|
||||
}
|
||||
return this.prepareDone(connection);
|
||||
}
|
||||
|
||||
prepareDone(connection) {
|
||||
const statement = new PreparedStatementInfo(
|
||||
this.query,
|
||||
this.id,
|
||||
this.fields,
|
||||
this.parameterDefinitions,
|
||||
connection
|
||||
);
|
||||
connection._statements.set(this.key, statement);
|
||||
if (this.onResult) {
|
||||
this.onResult(null, statement);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Prepare;
|
279
node_modules/mysql2/lib/commands/query.js
generated
vendored
Normal file
279
node_modules/mysql2/lib/commands/query.js
generated
vendored
Normal file
@ -0,0 +1,279 @@
|
||||
'use strict';
|
||||
|
||||
const process = require('process');
|
||||
|
||||
const Readable = require('stream').Readable;
|
||||
|
||||
const Command = require('./command.js');
|
||||
const Packets = require('../packets/index.js');
|
||||
const getTextParser = require('../parsers/text_parser.js');
|
||||
const ServerStatus = require('../constants/server_status.js');
|
||||
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
||||
|
||||
const EmptyPacket = new Packets.Packet(0, Buffer.allocUnsafe(4), 0, 4);
|
||||
|
||||
// http://dev.mysql.com/doc/internals/en/com-query.html
|
||||
class Query extends Command {
|
||||
constructor(options, callback) {
|
||||
super();
|
||||
this.sql = options.sql;
|
||||
this.values = options.values;
|
||||
this._queryOptions = options;
|
||||
this.namedPlaceholders = options.namedPlaceholders || false;
|
||||
this.onResult = callback;
|
||||
this._fieldCount = 0;
|
||||
this._rowParser = null;
|
||||
this._fields = [];
|
||||
this._rows = [];
|
||||
this._receivedFieldsCount = 0;
|
||||
this._resultIndex = 0;
|
||||
this._localStream = null;
|
||||
this._unpipeStream = function() {};
|
||||
this._streamFactory = options.infileStreamFactory;
|
||||
this._connection = null;
|
||||
}
|
||||
|
||||
then() {
|
||||
const err =
|
||||
"You have tried to call .then(), .catch(), or invoked await on the result of query that is not a promise, which is a programming error. Try calling con.promise().query(), or require('mysql2/promise') instead of 'mysql2' for a promise-compatible version of the query interface. To learn how to use async/await or Promises check out documentation at https://www.npmjs.com/package/mysql2#using-promise-wrapper, or the mysql2 documentation at https://github.com/sidorares/node-mysql2/tree/master/documentation/Promise-Wrapper.md";
|
||||
// eslint-disable-next-line
|
||||
console.log(err);
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
start(packet, connection) {
|
||||
if (connection.config.debug) {
|
||||
// eslint-disable-next-line
|
||||
console.log(' Sending query command: %s', this.sql);
|
||||
}
|
||||
this._connection = connection;
|
||||
this.options = Object.assign({}, connection.config, this._queryOptions);
|
||||
const cmdPacket = new Packets.Query(
|
||||
this.sql,
|
||||
connection.config.charsetNumber
|
||||
);
|
||||
connection.writePacket(cmdPacket.toPacket(1));
|
||||
return Query.prototype.resultsetHeader;
|
||||
}
|
||||
|
||||
done() {
|
||||
this._unpipeStream();
|
||||
if (this.onResult) {
|
||||
let rows, fields;
|
||||
if (this._resultIndex === 0) {
|
||||
rows = this._rows[0];
|
||||
fields = this._fields[0];
|
||||
} else {
|
||||
rows = this._rows;
|
||||
fields = this._fields;
|
||||
}
|
||||
if (fields) {
|
||||
process.nextTick(() => {
|
||||
this.onResult(null, rows, fields);
|
||||
});
|
||||
} else {
|
||||
process.nextTick(() => {
|
||||
this.onResult(null, rows);
|
||||
});
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
doneInsert(rs) {
|
||||
if (this._localStreamError) {
|
||||
if (this.onResult) {
|
||||
this.onResult(this._localStreamError, rs);
|
||||
} else {
|
||||
this.emit('error', this._localStreamError);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
this._rows.push(rs);
|
||||
this._fields.push(void 0);
|
||||
this.emit('fields', void 0);
|
||||
this.emit('result', rs);
|
||||
if (rs.serverStatus & ServerStatus.SERVER_MORE_RESULTS_EXISTS) {
|
||||
this._resultIndex++;
|
||||
return this.resultsetHeader;
|
||||
}
|
||||
return this.done();
|
||||
}
|
||||
|
||||
resultsetHeader(packet, connection) {
|
||||
const rs = new Packets.ResultSetHeader(packet, connection);
|
||||
this._fieldCount = rs.fieldCount;
|
||||
if (connection.config.debug) {
|
||||
// eslint-disable-next-line
|
||||
console.log(
|
||||
` Resultset header received, expecting ${rs.fieldCount} column definition packets`
|
||||
);
|
||||
}
|
||||
if (this._fieldCount === 0) {
|
||||
return this.doneInsert(rs);
|
||||
}
|
||||
if (this._fieldCount === null) {
|
||||
return this._streamLocalInfile(connection, rs.infileName);
|
||||
}
|
||||
this._receivedFieldsCount = 0;
|
||||
this._rows.push([]);
|
||||
this._fields.push([]);
|
||||
return this.readField;
|
||||
}
|
||||
|
||||
_streamLocalInfile(connection, path) {
|
||||
if (this._streamFactory) {
|
||||
this._localStream = this._streamFactory(path);
|
||||
} else {
|
||||
this._localStreamError = new Error(
|
||||
`As a result of LOCAL INFILE command server wants to read ${path} file, but as of v2.0 you must provide streamFactory option returning ReadStream.`
|
||||
);
|
||||
connection.writePacket(EmptyPacket);
|
||||
return this.infileOk;
|
||||
}
|
||||
|
||||
const onConnectionError = () => {
|
||||
this._unpipeStream();
|
||||
};
|
||||
const onDrain = () => {
|
||||
this._localStream.resume();
|
||||
};
|
||||
const onPause = () => {
|
||||
this._localStream.pause();
|
||||
};
|
||||
const onData = function(data) {
|
||||
const dataWithHeader = Buffer.allocUnsafe(data.length + 4);
|
||||
data.copy(dataWithHeader, 4);
|
||||
connection.writePacket(
|
||||
new Packets.Packet(0, dataWithHeader, 0, dataWithHeader.length)
|
||||
);
|
||||
};
|
||||
const onEnd = () => {
|
||||
connection.removeListener('error', onConnectionError);
|
||||
connection.writePacket(EmptyPacket);
|
||||
};
|
||||
const onError = err => {
|
||||
this._localStreamError = err;
|
||||
connection.removeListener('error', onConnectionError);
|
||||
connection.writePacket(EmptyPacket);
|
||||
};
|
||||
this._unpipeStream = () => {
|
||||
connection.stream.removeListener('pause', onPause);
|
||||
connection.stream.removeListener('drain', onDrain);
|
||||
this._localStream.removeListener('data', onData);
|
||||
this._localStream.removeListener('end', onEnd);
|
||||
this._localStream.removeListener('error', onError);
|
||||
};
|
||||
connection.stream.on('pause', onPause);
|
||||
connection.stream.on('drain', onDrain);
|
||||
this._localStream.on('data', onData);
|
||||
this._localStream.on('end', onEnd);
|
||||
this._localStream.on('error', onError);
|
||||
connection.once('error', onConnectionError);
|
||||
return this.infileOk;
|
||||
}
|
||||
|
||||
readField(packet, connection) {
|
||||
this._receivedFieldsCount++;
|
||||
// Often there is much more data in the column definition than in the row itself
|
||||
// If you set manually _fields[0] to array of ColumnDefinition's (from previous call)
|
||||
// you can 'cache' result of parsing. Field packets still received, but ignored in that case
|
||||
// this is the reason _receivedFieldsCount exist (otherwise we could just use current length of fields array)
|
||||
if (this._fields[this._resultIndex].length !== this._fieldCount) {
|
||||
const field = new Packets.ColumnDefinition(
|
||||
packet,
|
||||
connection.clientEncoding
|
||||
);
|
||||
this._fields[this._resultIndex].push(field);
|
||||
if (connection.config.debug) {
|
||||
/* eslint-disable no-console */
|
||||
console.log(' Column definition:');
|
||||
console.log(` name: ${field.name}`);
|
||||
console.log(` type: ${field.columnType}`);
|
||||
console.log(` flags: ${field.flags}`);
|
||||
/* eslint-enable no-console */
|
||||
}
|
||||
}
|
||||
// last field received
|
||||
if (this._receivedFieldsCount === this._fieldCount) {
|
||||
const fields = this._fields[this._resultIndex];
|
||||
this.emit('fields', fields);
|
||||
this._rowParser = getTextParser(fields, this.options, connection.config);
|
||||
return Query.prototype.fieldsEOF;
|
||||
}
|
||||
return Query.prototype.readField;
|
||||
}
|
||||
|
||||
fieldsEOF(packet, connection) {
|
||||
// check EOF
|
||||
if (!packet.isEOF()) {
|
||||
return connection.protocolError('Expected EOF packet');
|
||||
}
|
||||
return this.row;
|
||||
}
|
||||
|
||||
row(packet) {
|
||||
if (packet.isEOF()) {
|
||||
const status = packet.eofStatusFlags();
|
||||
const moreResults = status & ServerStatus.SERVER_MORE_RESULTS_EXISTS;
|
||||
if (moreResults) {
|
||||
this._resultIndex++;
|
||||
return Query.prototype.resultsetHeader;
|
||||
}
|
||||
return this.done();
|
||||
}
|
||||
let row;
|
||||
try {
|
||||
row = new this._rowParser(
|
||||
packet,
|
||||
this._fields[this._resultIndex],
|
||||
this.options,
|
||||
CharsetToEncoding
|
||||
);
|
||||
} catch (err) {
|
||||
this._localStreamError = err;
|
||||
return this.doneInsert(null);
|
||||
}
|
||||
if (this.onResult) {
|
||||
this._rows[this._resultIndex].push(row);
|
||||
} else {
|
||||
this.emit('result', row);
|
||||
}
|
||||
return Query.prototype.row;
|
||||
}
|
||||
|
||||
infileOk(packet, connection) {
|
||||
const rs = new Packets.ResultSetHeader(packet, connection);
|
||||
return this.doneInsert(rs);
|
||||
}
|
||||
|
||||
stream(options) {
|
||||
options = options || {};
|
||||
options.objectMode = true;
|
||||
const stream = new Readable(options);
|
||||
stream._read = () => {
|
||||
this._connection && this._connection.resume();
|
||||
};
|
||||
this.on('result', row => {
|
||||
if (!stream.push(row)) {
|
||||
this._connection.pause();
|
||||
}
|
||||
stream.emit('result', row); // replicate old emitter
|
||||
});
|
||||
this.on('error', err => {
|
||||
stream.emit('error', err); // Pass on any errors
|
||||
});
|
||||
this.on('end', () => {
|
||||
stream.push(null); // pushing null, indicating EOF
|
||||
stream.emit('close'); // notify readers that query has completed
|
||||
});
|
||||
this.on('fields', fields => {
|
||||
stream.emit('fields', fields); // replicate old emitter
|
||||
});
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
Query.prototype.catch = Query.prototype.then;
|
||||
|
||||
module.exports = Query;
|
29
node_modules/mysql2/lib/commands/quit.js
generated
vendored
Normal file
29
node_modules/mysql2/lib/commands/quit.js
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
const Command = require('./command.js');
|
||||
const CommandCode = require('../constants/commands.js');
|
||||
const Packet = require('../packets/packet.js');
|
||||
|
||||
class Quit extends Command {
|
||||
constructor(callback) {
|
||||
super();
|
||||
this.done = callback;
|
||||
}
|
||||
|
||||
start(packet, connection) {
|
||||
connection._closing = true;
|
||||
const quit = new Packet(
|
||||
0,
|
||||
Buffer.from([1, 0, 0, 0, CommandCode.QUIT]),
|
||||
0,
|
||||
5
|
||||
);
|
||||
if (this.done) {
|
||||
this.done();
|
||||
}
|
||||
connection.writePacket(quit);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Quit;
|
27
node_modules/mysql2/lib/commands/register_slave.js
generated
vendored
Normal file
27
node_modules/mysql2/lib/commands/register_slave.js
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
const Command = require('./command');
|
||||
const Packets = require('../packets');
|
||||
|
||||
class RegisterSlave extends Command {
|
||||
constructor(opts, callback) {
|
||||
super();
|
||||
this.onResult = callback;
|
||||
this.opts = opts;
|
||||
}
|
||||
|
||||
start(packet, connection) {
|
||||
const newPacket = new Packets.RegisterSlave(this.opts);
|
||||
connection.writePacket(newPacket.toPacket(1));
|
||||
return RegisterSlave.prototype.registerResponse;
|
||||
}
|
||||
|
||||
registerResponse() {
|
||||
if (this.onResult) {
|
||||
process.nextTick(this.onResult.bind(this));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RegisterSlave;
|
162
node_modules/mysql2/lib/commands/server_handshake.js
generated
vendored
Normal file
162
node_modules/mysql2/lib/commands/server_handshake.js
generated
vendored
Normal file
@ -0,0 +1,162 @@
|
||||
'use strict';
|
||||
|
||||
const CommandCode = require('../constants/commands.js');
|
||||
const Errors = require('../constants/errors.js');
|
||||
|
||||
const Command = require('./command.js');
|
||||
const Packets = require('../packets/index.js');
|
||||
|
||||
class ServerHandshake extends Command {
|
||||
constructor(args) {
|
||||
super();
|
||||
this.args = args;
|
||||
/*
|
||||
this.protocolVersion = args.protocolVersion || 10;
|
||||
this.serverVersion = args.serverVersion;
|
||||
this.connectionId = args.connectionId,
|
||||
this.statusFlags = args.statusFlags,
|
||||
this.characterSet = args.characterSet,
|
||||
this.capabilityFlags = args.capabilityFlags || 512;
|
||||
*/
|
||||
}
|
||||
|
||||
start(packet, connection) {
|
||||
const serverHelloPacket = new Packets.Handshake(this.args);
|
||||
this.serverHello = serverHelloPacket;
|
||||
serverHelloPacket.setScrambleData(err => {
|
||||
if (err) {
|
||||
connection.emit('error', new Error('Error generating random bytes'));
|
||||
return;
|
||||
}
|
||||
connection.writePacket(serverHelloPacket.toPacket(0));
|
||||
});
|
||||
return ServerHandshake.prototype.readClientReply;
|
||||
}
|
||||
|
||||
readClientReply(packet, connection) {
|
||||
// check auth here
|
||||
const clientHelloReply = Packets.HandshakeResponse.fromPacket(packet);
|
||||
// TODO check we don't have something similar already
|
||||
connection.clientHelloReply = clientHelloReply;
|
||||
if (this.args.authCallback) {
|
||||
this.args.authCallback(
|
||||
{
|
||||
user: clientHelloReply.user,
|
||||
database: clientHelloReply.database,
|
||||
address: connection.stream.remoteAddress,
|
||||
authPluginData1: this.serverHello.authPluginData1,
|
||||
authPluginData2: this.serverHello.authPluginData2,
|
||||
authToken: clientHelloReply.authToken
|
||||
},
|
||||
(err, mysqlError) => {
|
||||
// if (err)
|
||||
if (!mysqlError) {
|
||||
connection.writeOk();
|
||||
} else {
|
||||
// TODO create constants / errorToCode
|
||||
// 1045 = ER_ACCESS_DENIED_ERROR
|
||||
connection.writeError({
|
||||
message: mysqlError.message || '',
|
||||
code: mysqlError.code || 1045
|
||||
});
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
connection.writeOk();
|
||||
}
|
||||
return ServerHandshake.prototype.dispatchCommands;
|
||||
}
|
||||
|
||||
dispatchCommands(packet, connection) {
|
||||
// command from client to server
|
||||
let knownCommand = true;
|
||||
const encoding = connection.clientHelloReply.encoding;
|
||||
const commandCode = packet.readInt8();
|
||||
switch (commandCode) {
|
||||
case CommandCode.QUIT:
|
||||
if (connection.listeners('quit').length) {
|
||||
connection.emit('quit');
|
||||
} else {
|
||||
connection.stream.end();
|
||||
}
|
||||
break;
|
||||
case CommandCode.INIT_DB:
|
||||
if (connection.listeners('init_db').length) {
|
||||
const schemaName = packet.readString(undefined, encoding);
|
||||
connection.emit('init_db', schemaName);
|
||||
} else {
|
||||
connection.writeOk();
|
||||
}
|
||||
break;
|
||||
case CommandCode.QUERY:
|
||||
if (connection.listeners('query').length) {
|
||||
const query = packet.readString(undefined, encoding);
|
||||
connection.emit('query', query);
|
||||
} else {
|
||||
connection.writeError({
|
||||
code: Errors.HA_ERR_INTERNAL_ERROR,
|
||||
message: 'No query handler'
|
||||
});
|
||||
}
|
||||
break;
|
||||
case CommandCode.FIELD_LIST:
|
||||
if (connection.listeners('field_list').length) {
|
||||
const table = packet.readNullTerminatedString();
|
||||
const fields = packet.readString(undefined, encoding);
|
||||
connection.emit('field_list', table, fields);
|
||||
} else {
|
||||
connection.writeError({
|
||||
code: Errors.ER_WARN_DEPRECATED_SYNTAX,
|
||||
message:
|
||||
'As of MySQL 5.7.11, COM_FIELD_LIST is deprecated and will be removed in a future version of MySQL.'
|
||||
});
|
||||
}
|
||||
break;
|
||||
case CommandCode.PING:
|
||||
if (connection.listeners('ping').length) {
|
||||
connection.emit('ping');
|
||||
} else {
|
||||
connection.writeOk();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
knownCommand = false;
|
||||
}
|
||||
if (connection.listeners('packet').length) {
|
||||
connection.emit('packet', packet.clone(), knownCommand, commandCode);
|
||||
} else if (!knownCommand) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Unknown command:', commandCode);
|
||||
}
|
||||
return ServerHandshake.prototype.dispatchCommands;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ServerHandshake;
|
||||
|
||||
// TODO: implement server-side 4.1 authentication
|
||||
/*
|
||||
4.1 authentication: (http://bazaar.launchpad.net/~mysql/mysql-server/5.5/view/head:/sql/password.c)
|
||||
|
||||
SERVER: public_seed=create_random_string()
|
||||
send(public_seed)
|
||||
|
||||
CLIENT: recv(public_seed)
|
||||
hash_stage1=sha1("password")
|
||||
hash_stage2=sha1(hash_stage1)
|
||||
reply=xor(hash_stage1, sha1(public_seed,hash_stage2)
|
||||
|
||||
// this three steps are done in scramble()
|
||||
|
||||
send(reply)
|
||||
|
||||
|
||||
SERVER: recv(reply)
|
||||
hash_stage1=xor(reply, sha1(public_seed,hash_stage2))
|
||||
candidate_hash2=sha1(hash_stage1)
|
||||
check(candidate_hash2==hash_stage2)
|
||||
|
||||
server stores sha1(sha1(password)) ( hash_stag2)
|
||||
*/
|
Reference in New Issue
Block a user