-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Add support for MySQL Connection Attributes #1241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 10 commits
71151ad
9057689
71a1948
7038d92
151e4dc
26b97ba
7d54949
e8f4d0d
aa0e7a0
2f9b253
3ab2571
b5117fc
9042bbd
7c87a56
1058830
00a09d8
f6f3d84
406e2a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -235,10 +235,15 @@ func (mc *mysqlConn) readHandshakePacket() (data []byte, plugin string, err erro | |
if len(data) > pos { | ||
// character set [1 byte] | ||
// status flags [2 bytes] | ||
pos += 1 + 2 | ||
|
||
// capability flags (upper 2 bytes) [2 bytes] | ||
mc.flags |= clientFlag(uint32(binary.LittleEndian.Uint16(data[pos:pos+2])) << 16) | ||
pos += 2 | ||
|
||
// length of auth-plugin-data [1 byte] | ||
// reserved (all [00]) [10 bytes] | ||
pos += 1 + 2 + 2 + 1 + 10 | ||
pos += 1 + 10 | ||
|
||
// second part of the password cipher [mininum 13 bytes], | ||
// where len=MAX(13, length of auth-plugin-data - 8) | ||
|
@@ -305,16 +310,37 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string | |
var authRespLEIBuf [9]byte | ||
authRespLen := len(authResp) | ||
authRespLEI := appendLengthEncodedInteger(authRespLEIBuf[:0], uint64(authRespLen)) | ||
if len(authRespLEI) > 1 { | ||
if len(authRespLEI) > 1 && clientFlags&clientSecureConn != 0 { | ||
andygrunwald marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// if the length can not be written in 1 byte, it must be written as a | ||
// length encoded integer | ||
clientFlags |= clientPluginAuthLenEncClientData | ||
} | ||
|
||
pktLen := 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1 + len(authRespLEI) + len(authResp) + 21 + 1 | ||
if clientFlags&clientSecureConn == 0 || clientFlags&clientPluginAuthLenEncClientData == 0 { | ||
pktLen++ | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @andygrunwald – any context on this one? Tests pass correctly without this block. I'll dig in deeper if you don't remember why this was needed. |
||
|
||
connectAttrsBuf := make([]byte, 0, 100) | ||
if mc.flags&clientConnectAttrs != 0 { | ||
clientFlags |= clientConnectAttrs | ||
connectAttrsBuf = appendLengthEncodedString(connectAttrsBuf, []byte("_client_name")) | ||
connectAttrsBuf = appendLengthEncodedString(connectAttrsBuf, []byte("go-mysql-driver")) | ||
methane marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
for k, v := range mc.cfg.ConnectAttrs { | ||
if k == "_client_name" { | ||
// do not allow overwriting reserved values | ||
andygrunwald marked this conversation as resolved.
Show resolved
Hide resolved
|
||
continue | ||
} | ||
connectAttrsBuf = appendLengthEncodedString(connectAttrsBuf, []byte(k)) | ||
connectAttrsBuf = appendLengthEncodedString(connectAttrsBuf, []byte(v)) | ||
} | ||
connectAttrsBuf = appendLengthEncodedString(make([]byte, 0, 100), connectAttrsBuf) | ||
pktLen += len(connectAttrsBuf) | ||
} | ||
|
||
// To specify a db name | ||
if n := len(mc.cfg.DBName); n > 0 { | ||
if n := len(mc.cfg.DBName); mc.flags&clientConnectWithDB != 0 && n > 0 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. revert this. |
||
clientFlags |= clientConnectWithDB | ||
pktLen += n + 1 | ||
} | ||
|
@@ -380,20 +406,39 @@ func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string | |
data[pos] = 0x00 | ||
pos++ | ||
|
||
// Auth Data [length encoded integer] | ||
pos += copy(data[pos:], authRespLEI) | ||
// Auth Data [length encoded integer + data] if clientPluginAuthLenEncClientData | ||
// clientSecureConn => 1 byte len + data | ||
// else null-terminated | ||
if clientFlags&clientPluginAuthLenEncClientData != 0 { | ||
pos += copy(data[pos:], authRespLEI) | ||
} else if clientFlags&clientSecureConn != 0 { | ||
data[pos] = uint8(len(authResp)) | ||
pos++ | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this needed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @andygrunwald – do you remember any context on this one? I tried removing this block and confirmed many tests fail. I'll dig in deeper tomorrow, but wanted to start off seeing if you remembered this code. |
||
pos += copy(data[pos:], authResp) | ||
if clientFlags&clientSecureConn == 0 && clientFlags&clientPluginAuthLenEncClientData == 0 { | ||
data[pos] = 0x00 | ||
pos++ | ||
} | ||
|
||
// Databasename [null terminated string] | ||
if len(mc.cfg.DBName) > 0 { | ||
if clientFlags&clientConnectWithDB != 0 { | ||
pos += copy(data[pos:], mc.cfg.DBName) | ||
data[pos] = 0x00 | ||
pos++ | ||
} | ||
|
||
pos += copy(data[pos:], plugin) | ||
data[pos] = 0x00 | ||
pos++ | ||
// auth plugin name [null terminated string] | ||
if clientFlags&clientPluginAuth != 0 { | ||
pos += copy(data[pos:], plugin) | ||
data[pos] = 0x00 | ||
pos++ | ||
} | ||
|
||
// connection attributes [lenenc-int total + lenenc-str key-value pairs] | ||
if clientFlags&clientConnectAttrs != 0 { | ||
pos += copy(data[pos:], connectAttrsBuf) | ||
} | ||
|
||
// Send Auth packet | ||
return mc.writePacket(data[:pos]) | ||
|
Uh oh!
There was an error while loading. Please reload this page.