Created
September 18, 2011 19:24
-
-
Save cwarden/1225444 to your computer and use it in GitHub Desktop.
MySQL-Proxy Mock Server/JDBC Bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ javac MysqlProxyTest.java | |
$ mysql-proxy --plugins=proxy --proxy-lua-script="$(pwd)/mock-server.lua" --proxy-address 127.0.0.1:4040 --daemon | |
$ java -cp .:./mysql-connector-java-5.1.17-bin.jar MysqlProxyTest | |
Cannot connect to database server: | |
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure | |
The last packet successfully received from the server was 41 milliseconds ago. The last packet sent successfully to the server was 11 milliseconds ago. | |
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) | |
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) | |
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) | |
at java.lang.reflect.Constructor.newInstance(Constructor.java:532) | |
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) | |
at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116) | |
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:3090) | |
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2979) | |
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3520) | |
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1990) | |
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2151) | |
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2619) | |
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2569) | |
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1521) | |
at com.mysql.jdbc.ConnectionImpl.loadServerVariables(ConnectionImpl.java:3865) | |
at com.mysql.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:3404) | |
at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2385) | |
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2154) | |
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:792) | |
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) | |
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) | |
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) | |
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) | |
at java.lang.reflect.Constructor.newInstance(Constructor.java:532) | |
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) | |
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:381) | |
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:305) | |
at java.sql.DriverManager.getConnection(DriverManager.java:620) | |
at java.sql.DriverManager.getConnection(DriverManager.java:200) | |
at MysqlProxyTest.main(MysqlProxyTest.java:15) | |
Caused by: java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost. | |
at com.mysql.jdbc.MysqlIO.readFully(MysqlIO.java:2540) | |
at com.mysql.jdbc.MysqlIO.reuseAndReadPacket(MysqlIO.java:2990) | |
... 23 more |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ $%BEGINLICENSE%$ | |
Copyright (C) 2009 MySQL AB, 2009 Sun Microsystems, Inc | |
This program is free software; you can redistribute it and/or modify | |
it under the terms of the GNU General Public License as published by | |
the Free Software Foundation; version 2 of the License. | |
This program is distributed in the hope that it will be useful, | |
but WITHOUT ANY WARRANTY; without even the implied warranty of | |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
GNU General Public License for more details. | |
You should have received a copy of the GNU General Public License | |
along with this program; if not, write to the Free Software | |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
$%ENDLICENSE%$ --]] | |
--[[ ====================================================================== ]]-- | |
function packet_auth(fields) | |
fields = fields or { } | |
return "\010" .. -- proto version | |
(fields.version or "5.0.45-proxy") .. -- version | |
"\000" .. -- term-null | |
"\255\255\255\255" .. -- thread-id | |
"\000\020\000\000" .. | |
"\000\000\000\000" .. -- challenge - part I | |
"\000" .. -- filler | |
"\001\130" .. -- server cap (long pass, 4.1 proto) | |
"\008" .. -- charset | |
"\002\000" .. -- status | |
("\000"):rep(26) -- filler & challenge - part II | |
end | |
--[[ ====================================================================== ]]-- | |
function connect_server() | |
-- emulate a server | |
proxy.response = { | |
type = proxy.MYSQLD_PACKET_RAW, | |
packets = { | |
packet_auth() | |
} | |
} | |
return proxy.PROXY_SEND_RESULT | |
end | |
--[[ ====================================================================== ]]-- | |
function read_query( packet ) | |
if (string.byte(packet) == proxy.COM_QUIT) | |
or (string.byte(packet) == proxy.COM_INIT_DB) then | |
-- This gets called when you disconnect from the server | |
-- or when you specify a database on connection time | |
proxy.response.type = proxy.MYSQLD_PACKET_OK | |
return proxy.PROXY_SEND_RESULT | |
elseif string.byte(packet) == proxy.COM_QUERY then | |
if packet:sub(2) == "SHOW DATABASES" then | |
return show_databases() | |
else | |
-- Unkown query | |
return error_result ( | |
"I haven't learnt how to handle that query" | |
, '101' | |
, '!101') | |
end | |
end | |
end -- End of read_query() | |
--[[ ====================================================================== ]]-- | |
function error_result (msg, code, state) | |
proxy.response = { | |
type = proxy.MYSQLD_PACKET_ERR, | |
errmsg = msg, | |
errcode = code, | |
sqlstate = state, | |
} | |
return proxy.PROXY_SEND_RESULT | |
end | |
--[[ ====================================================================== ]]-- | |
function show_databases() | |
proxy.response.type = proxy.MYSQLD_PACKET_OK | |
proxy.response.resultset = { | |
fields = { | |
{ type = proxy.MYSQL_TYPE_STRING, name = "Database", }, | |
}, | |
rows = {} | |
} | |
-- here we add 70 database names to the resulset | |
for i = 1, 70 do | |
table.insert( | |
proxy.response.resultset.rows, | |
{"db_" .. i}) | |
end | |
return proxy.PROXY_SEND_RESULT | |
end | |
--[[ ====================================================================== ]]-- | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.sql.*; | |
public class MysqlProxyTest | |
{ | |
public static void main (String[] args) | |
{ | |
Connection conn = null; | |
try | |
{ | |
String userName = "test"; | |
String password = "test"; | |
String url = "jdbc:mysql://127.0.0.1:4040/"; | |
Class.forName ("com.mysql.jdbc.Driver").newInstance (); | |
conn = DriverManager.getConnection (url, userName, password); | |
System.out.println ("Database connection established"); | |
} | |
catch (Exception e) | |
{ | |
System.err.println ("Cannot connect to database server: "); | |
e.printStackTrace(); | |
} | |
finally | |
{ | |
if (conn != null) | |
{ | |
try | |
{ | |
conn.close (); | |
System.out.println ("Database connection terminated"); | |
} | |
catch (Exception e) { /* ignore close errors */ } | |
} | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment