Skip to content

Commit e2959fd

Browse files
committed
Add support for connection attributes.
This sets attribute _client_name with the value "Go MySQL Driver" Also sets _os, _platform, _pid and program_name by default.
1 parent 66b7d5c commit e2959fd

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

AUTHORS

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Aaron Hopkins <go-sql-driver at die.net>
1515
Arne Hormann <arnehormann at gmail.com>
1616
Carlos Nieto <jose.carlos at menteslibres.net>
1717
Chris Moos <chris at tech9computers.com>
18+
Daniël van Eeden <daniel.van.eeden at myname.nl>
1819
DisposaBoy <disposaboy at dby.me>
1920
Frederick Mayle <frederickmayle at gmail.com>
2021
Gustavo Kristic <gkristic at gmail.com>

driver.go

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"database/sql"
2121
"database/sql/driver"
2222
"net"
23+
"os"
24+
"strconv"
2325
)
2426

2527
// This struct is exported to make the driver directly accessible.
@@ -30,6 +32,8 @@ type MySQLDriver struct{}
3032
// Custom dial functions must be registered with RegisterDial
3133
type DialFunc func(addr string) (net.Conn, error)
3234

35+
var pid string
36+
3337
var dials map[string]DialFunc
3438

3539
// RegisterDial registers a custom dial function. It can then be used by the
@@ -145,5 +149,6 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
145149
}
146150

147151
func init() {
152+
pid = strconv.Itoa(os.Getpid())
148153
sql.Register("mysql", &MySQLDriver{})
149154
}

packets.go

+33
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import (
1616
"fmt"
1717
"io"
1818
"math"
19+
"os"
20+
"path"
21+
"runtime"
1922
"time"
2023
)
2124

@@ -219,6 +222,7 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
219222
clientTransactions |
220223
clientLocalFiles |
221224
clientPluginAuth |
225+
clientConnectAttrs |
222226
mc.flags&clientLongFlag
223227

224228
if mc.cfg.clientFoundRows {
@@ -233,7 +237,23 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
233237
// User Password
234238
scrambleBuff := scramblePassword(cipher, []byte(mc.cfg.passwd))
235239

240+
attrs := map[string]string {
241+
"_os": runtime.GOOS,
242+
"_client_name": "Go-MySQL-Driver",
243+
"_pid": pid,
244+
"_platform": runtime.GOARCH,
245+
"program_name": path.Base(os.Args[0]),
246+
}
247+
248+
attrlen := 0
249+
for attrname, attrvalue := range attrs {
250+
attrlen += len(attrname) + len(attrvalue)
251+
// one byte to store attrname length and one byte to store attrvalue length
252+
attrlen += 2
253+
}
254+
236255
pktLen := 4 + 4 + 1 + 23 + len(mc.cfg.user) + 1 + 1 + len(scrambleBuff) + 21 + 1
256+
pktLen += attrlen + 1 // one byte to store the total length of attrs
237257

238258
// To specify a db name
239259
if n := len(mc.cfg.dbname); n > 0 {
@@ -305,6 +325,19 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
305325
// Assume native client during response
306326
pos += copy(data[pos:], "mysql_native_password")
307327
data[pos] = 0x00
328+
pos++
329+
330+
// Connection attributes
331+
data[pos] = byte(attrlen)
332+
pos++
333+
334+
for attrname, attrvalue := range attrs {
335+
data[pos] = byte(len(attrname))
336+
pos += 1 + copy(data[pos+1:], attrname)
337+
338+
data[pos] = byte(len(attrvalue))
339+
pos += 1 + copy(data[pos+1:], attrvalue)
340+
}
308341

309342
// Send Auth packet
310343
return mc.writePacket(data)

0 commit comments

Comments
 (0)