Skip to content

Commit c7e6ad6

Browse files
author
Andrey Sidorov
committed
WIP: pass encoding to writers and readers
1 parent 9fea6c7 commit c7e6ad6

File tree

10 files changed

+42
-28
lines changed

10 files changed

+42
-28
lines changed

lib/commands/client_handshake.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ var util = require('util');
33
var Command = require('./command.js');
44
var Packets = require('../packets/index.js');
55
var ClientConstants = require('../constants/client.js');
6+
var CharsetToEncoding = require('../constants/charset_encodings.js');
67

78
function ClientHandshake (clientFlags)
89
{
@@ -85,6 +86,7 @@ ClientHandshake.prototype.handshakeInit = function (helloPacket, connection) {
8586
flagNames(this.handshake.capabilityFlags).join(', '));
8687
}
8788
connection.serverCapabilityFlags = this.handshake.capabilityFlags;
89+
connection.serverEncoding = CharsetToEncoding[this.handshake.characterSet];
8890
connection.connectionId = this.handshake.connectionId;
8991
var serverSSLSupport = this.handshake.capabilityFlags & ClientConstants.SSL;
9092

lib/commands/command.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Command.prototype.execute = function (packet, connection) {
2525
}
2626

2727
if (packet && packet.isError()) {
28-
var err = packet.asError();
28+
var err = packet.asError(connection.serverEncoding);
2929
if (this.onResult) {
3030
this.onResult(err);
3131
} else {

lib/commands/server_handshake.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ ServerHandshake.prototype.start = function (packet, connection) {
3939
ServerHandshake.prototype.readClientReply = function (packet, connection) {
4040
// check auth here
4141
var clientHelloReply = new Packets.HandshakeResponse.fromPacket(packet);
42+
43+
// TODO check we don't have something similar already
44+
connection.clientHelloReply = clientHelloReply;
45+
4246
if (this.args.authCallback) {
4347
try {
4448
this.args.authCallback({
@@ -73,6 +77,7 @@ ServerHandshake.prototype.readClientReply = function (packet, connection) {
7377
ServerHandshake.prototype.dispatchCommands = function (packet, connection) {
7478
// command from client to server
7579
var knownCommand = true;
80+
var encoding = connection.clientHelloReply.encoding;
7681
var commandCode = packet.readInt8();
7782
switch (commandCode) {
7883
case CommandCode.QUIT:
@@ -85,7 +90,7 @@ ServerHandshake.prototype.dispatchCommands = function (packet, connection) {
8590

8691
case CommandCode.INIT_DB:
8792
if (connection.listeners('init_db').length) {
88-
var schemaName = packet.readString();
93+
var schemaName = packet.readString(encoding);
8994
connection.emit('init_db', schemaName);
9095
} else {
9196
connection.writeOk();
@@ -94,7 +99,7 @@ ServerHandshake.prototype.dispatchCommands = function (packet, connection) {
9499

95100
case CommandCode.QUERY:
96101
if (connection.listeners('query').length) {
97-
var query = packet.readString();
102+
var query = packet.readString(encoding);
98103
connection.emit('query', query);
99104
} else {
100105
connection.writeError({
@@ -107,7 +112,7 @@ ServerHandshake.prototype.dispatchCommands = function (packet, connection) {
107112
case CommandCode.FIELD_LIST:
108113
if (connection.listeners('field_list').length) {
109114
var table = packet.readNullTerminatedString();
110-
var fields = packet.readString();
115+
var fields = packet.readString(encoding);
111116
connection.emit('field_list', table, fields);
112117
} else {
113118
connection.writeError({

lib/connection.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ var Packet = require('./packets/packet.js');
1111
var Packets = require('./packets/index.js');
1212
var Commands = require('./commands/index.js');
1313
var ConnectionConfig = require('./connection_config.js');
14+
var CharsetToEncoding = require('./constants/charset_encodings.js');
1415

1516
var _connectionId = 0;
1617
var noop = function () {};
@@ -691,14 +692,16 @@ Connection.prototype.writeOk = function (args) {
691692
if (!args) {
692693
args = {affectedRows: 0};
693694
}
694-
this.writePacket(Packets.OK.toPacket(args));
695+
this.writePacket(Packets.OK.toPacket(args, this.serverConfig.encoding));
695696
};
696697

697698
Connection.prototype.writeError = function (args) {
698-
this.writePacket(Packets.Error.toPacket(args));
699+
this.writePacket(Packets.Error.toPacket(args, this.serverConfig.encoding));
699700
};
700701

701702
Connection.prototype.serverHandshake = function serverHandshake (args) {
703+
this.serverConfig = args;
704+
this.serverConfig.encoding = CharsetToEncoding[this.serverConfig.characterSet];
702705
return this.addCommand(new Commands.ServerHandshake(args));
703706
};
704707

lib/packets/column_definition.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var Buffer = require('safe-buffer').Buffer;
22
var Packet = require('../packets/packet');
33
var StringParser = require('../parsers/string');
4+
var CharsetToEncoding = require('../constants/charset_encodings.js');
45

56
// creating JS string is relatively expensive (compared to
67
// reading few bytes from buffer) because all string properties
@@ -101,13 +102,13 @@ ColumnDefinition.toPacket = function (column, sequenceId)
101102
{
102103
var length = 17; // = 4 padding + 1 + 12 for the rest
103104
fields.forEach(function (field) {
104-
length += Packet.lengthCodedStringLength(column[field], this.characterSet);
105+
length += Packet.lengthCodedStringLength(column[field], CharsetToEncoding[column.characterSet]);
105106
});
106107

107108
var buffer = Buffer.allocUnsafe(length);
108109

109110
function writeField (name) {
110-
packet.writeLengthCodedString(column[name], this.characterSet);
111+
packet.writeLengthCodedString(column[name], CharsetToEncoding[column.characterSet]);
111112
}
112113
var packet = new Packet(sequenceId, buffer, 0, length);
113114
packet.offset = 4;

lib/packets/handshake_response.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ function HandshakeResponse (handshake)
2626
}
2727
this.authToken = authToken;
2828
this.charsetNumber = handshake.charsetNumber;
29+
this.encoding = CharsetToEncoding[handshake.charsetNumber];
2930
this.connectAttributes = handshake.connectAttributes;
3031
}
3132

@@ -83,7 +84,7 @@ HandshakeResponse.prototype.serializeResponse = function (buffer) {
8384
packet.writeInt8(this.charsetNumber);
8485
packet.skip(23);
8586

86-
var encoding = CharsetToEncoding[this.charsetNumber];
87+
var encoding = this.encoding;
8788
packet.writeNullTerminatedString(this.user, encoding);
8889

8990
var authTokenLength, k;
@@ -130,7 +131,6 @@ HandshakeResponse.prototype.toPacket = function ()
130131
}
131132
// dry run: calculate resulting packet length
132133
var p = this.serializeResponse(Packet.MockBuffer());
133-
134134
return this.serializeResponse(Buffer.allocUnsafe(p.offset));
135135
};
136136

lib/packets/index.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ module.exports.Packet = Packet;
2323
module.exports.OK = function OK () {
2424
};
2525

26-
module.exports.OK.toPacket = function (args) {
26+
module.exports.OK.toPacket = function (args, encoding) {
2727
args = args || {};
2828
var affectedRows = args.affectedRows || 0;
2929
var insertId = args.insertId || 0;
@@ -42,7 +42,7 @@ module.exports.OK.toPacket = function (args) {
4242
packet.writeLengthCodedNumber(insertId);
4343
packet.writeInt16(serverStatus);
4444
packet.writeInt16(warningCount);
45-
packet.writeString(message);
45+
packet.writeString(message, encoding);
4646
packet._name = 'OK';
4747
return packet;
4848
};
@@ -70,14 +70,15 @@ module.exports.EOF.toPacket = function (warnings, statusFlags) {
7070
module.exports.Error = function Error () {
7171
};
7272

73-
module.exports.Error.toPacket = function (args) {
73+
module.exports.Error.toPacket = function (args, encoding) {
7474
var length = 13 + Buffer.byteLength(args.message, 'utf8');
7575
var packet = new Packet(0, Buffer.allocUnsafe(length), 0, length);
7676
packet.offset = 4;
7777
packet.writeInt8(0xff);
7878
packet.writeInt16(args.code);
79-
packet.writeString('#_____');
80-
packet.writeString(args.message);
79+
// TODO: sql state parameter
80+
packet.writeString('#_____', encoding);
81+
packet.writeString(args.message, encoding);
8182
packet._name = 'Error';
8283
return packet;
8384
};

lib/packets/packet.js

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,12 @@ Packet.prototype.readNullTerminatedString = function (encoding) {
371371
};
372372

373373
// TODO reuse?
374-
Packet.prototype.readString = function (len) {
374+
Packet.prototype.readString = function (len, encoding) {
375375
if (typeof len == 'undefined') {
376376
len = this.end - this.offset;
377377
}
378378
this.offset += len;
379-
return this.buffer.utf8Slice(this.offset - len, this.offset);
379+
return StringParser.decode(this.buffer.slice(this.offset - len, this.offset), encoding);
380380
};
381381

382382
// The whole reason parse* function below exist
@@ -424,7 +424,7 @@ Packet.prototype.parseInt = function (len, supportBigNumbers) {
424424
var numDigits = end - this.offset;
425425
if (supportBigNumbers) {
426426
if (numDigits >= 15) {
427-
str = this.readString(end - this.offset);
427+
str = this.readString(end - this.offset, 'binary');
428428
result = parseInt(str, 10);
429429
if (result.toString() == str) {
430430
return sign * result;
@@ -632,7 +632,7 @@ Packet.prototype.parseLengthCodedInt = function (supportBigNumbers) {
632632
};
633633

634634
Packet.prototype.parseLengthCodedIntString = function () {
635-
return this.readString(this.readLengthCodedNumber());
635+
return this.readString(this.readLengthCodedNumber(), 'binary');
636636
};
637637

638638
Packet.prototype.parseLengthCodedFloat = function () {
@@ -653,7 +653,7 @@ Packet.prototype.isError = function () {
653653
return this.peekByte() == 0xff;
654654
};
655655

656-
Packet.prototype.asError = function () {
656+
Packet.prototype.asError = function (encoding) {
657657
this.reset();
658658

659659
var fieldCount = this.readInt8();
@@ -662,7 +662,7 @@ Packet.prototype.asError = function () {
662662
if (this.buffer[this.offset] == 0x23) {
663663
sqlState = this.readBuffer(6).toString();
664664
}
665-
var message = this.readString();
665+
var message = this.readString(undefined, encoding);
666666
var err = new Error(message);
667667
err.code = ErrorCodeToName[errorCode];
668668
err.errno = errorCode;
@@ -726,7 +726,7 @@ Packet.prototype.writeNull = function () {
726726
// TODO: refactor following three?
727727
Packet.prototype.writeNullTerminatedString = function (s, encoding) {
728728
var buf = StringParser.encode(s, encoding);
729-
buf.copy(this.buffer, this.offset);
729+
this.buffer.length && buf.copy(this.buffer, this.offset);
730730
this.offset += buf.length;
731731
this.writeInt8(0);
732732
};
@@ -747,16 +747,15 @@ Packet.prototype.writeString = function (s, encoding) {
747747
// this.offset += bytes;
748748

749749
var buf = StringParser.encode(s, encoding);
750-
buf.copy(this.buffer, this.offset);
750+
this.buffer.length && buf.copy(this.buffer, this.offset);
751751
this.offset += buf.length;
752752
};
753753

754754
Packet.prototype.writeLengthCodedString = function (s, encoding) {
755-
console.log('writeLengthCodedString ', s, encoding);
756755
var buf = StringParser.encode(s, encoding);
757756
this.writeLengthCodedNumber(buf.length);
758-
buf.copy(this.buffer, this.offset);
759-
this.offset += buf.lengh;
757+
this.buffer.length && buf.copy(this.buffer, this.offset);
758+
this.offset += buf.length;
760759
};
761760

762761
Packet.prototype.writeLengthCodedBuffer = function (b) {

lib/packets/text_row.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
var Buffer = require('safe-buffer').Buffer;
22
var Packet = require('../packets/packet');
3+
var CharsetToEncoding = require('../constants/charset_encodings.js');
34

45
function TextRow (columns)
56
{
@@ -24,7 +25,7 @@ TextRow.toPacket = function (column) {
2425
++length;
2526
return;
2627
}
27-
length += Packet.lengthCodedStringLength(val.toString(10));
28+
length += Packet.lengthCodedStringLength(val.toString(10), CharsetToEncoding[column.characterSet]);
2829
});
2930

3031
buffer = Buffer.allocUnsafe(length + 4);
@@ -39,7 +40,7 @@ TextRow.toPacket = function (column) {
3940
packet.writeInt8(0);
4041
return;
4142
}
42-
packet.writeLengthCodedString(val.toString(10));
43+
packet.writeLengthCodedString(val.toString(10), CharsetToEncoding[column.characterSet]);
4344
});
4445
return packet;
4546
};

test/integration/test-auth-switch.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ TestAuthSwitchHandshake.prototype.dispatchCommands = function (packet, connectio
6868
};
6969

7070
var server = mysql.createServer(function (conn) {
71+
conn.serverConfig = {};
72+
conn.serverConfig.encoding = 'cesu8';
7173
conn.addCommand(new TestAuthSwitchHandshake({
7274
pluginName: 'auth_test_plugin',
7375
pluginData: Buffer.from('f\{tU-{K@BhfHt/-4^Z,')

0 commit comments

Comments
 (0)