public ProtocolConnection openConnectionImpl(HostSpec[] hostSpecs, String user, String database, Properties info, Logger logger) throws SQLException {
// Extract interesting values from the info properties:
// - the SSL setting
boolean requireSSL;
boolean trySSL;
String sslmode = ("sslmode");
if (sslmode==null)
{ //Fall back to the ssl property
requireSSL = trySSL = (("ssl") != null);
} else {
if ("disable".equals(sslmode))
{
requireSSL = trySSL = false;
}
//allow and prefer are not handled yet
/*else if ("allow".equals(sslmode) || "prefer".equals(sslmode))
{
//XXX Allow and prefer are treated the same way
requireSSL = false;
trySSL = true;
}*/
else if ("require".equals(sslmode) || "verify-ca".equals(sslmode) || "verify-full".equals(sslmode))
{
requireSSL = trySSL = true;
} else {
throw new PSQLException (("Invalid sslmode value: {0}", sslmode), PSQLState.CONNECTION_UNABLE_TO_CONNECT);
}
}
// - the TCP keep alive setting
boolean requireTCPKeepAlive = (Boolean.valueOf(("tcpKeepAlive")).booleanValue());
// NOTE: To simplify this code, it is assumed that if we are
// using the V3 protocol, then the database is at least 7.4. That
// eliminates the need to check database versions and maintain
// backward-compatible code here.
//
// Change by Chris Smith <cdsmith@>
for (int whichHost = 0; whichHost < hostSpecs.length; ++whichHost) {
HostSpec hostSpec = hostSpecs[whichHost];
if (())
("Trying to establish a protocol version 3 connection to " + hostSpec);
//
// Establish a connection.
//
int connectTimeout = 0;
String connectTimeoutProperty = ("connectTimeout", "0");
try {
connectTimeout = (connectTimeoutProperty) * 1000;
} catch (NumberFormatException nfe) {
("Couldn't parse connectTimeout value:" + connectTimeoutProperty);
}
PGStream newStream = null;
try
{
newStream = new PGStream(hostSpec, connectTimeout);
// Construct and send an ssl startup packet if requested.
if (trySSL)
newStream = enableSSL(newStream, requireSSL, info, logger, connectTimeout);
// Set the socket timeout if the "socketTimeout" property has been set.
String socketTimeoutProperty = ("socketTimeout", "0");
try {
int socketTimeout = (socketTimeoutProperty);
if (socketTimeout > 0) {
().setSoTimeout(socketTimeout*1000);
}
} catch (NumberFormatException nfe) {
("Couldn't parse socketTimeout value:" + socketTimeoutProperty);
}
// Enable TCP keep-alive probe if required.
().setKeepAlive(requireTCPKeepAlive);
// Try to set SO_SNDBUF and SO_RECVBUF socket options, if requested.
// If receiveBufferSize and send_buffer_size are set to a value greater
// than 0, adjust. -1 means use the system default, 0 is ignored since not
// supported.
// Set SO_RECVBUF read buffer size
String receiveBufferSizeProperty = ("receiveBufferSize", "-1");
try {
int receiveBufferSize = (receiveBufferSizeProperty);
if (receiveBufferSize > -1) {
// value of 0 not a valid buffer size value
if (receiveBufferSize > 0) {
().setReceiveBufferSize(receiveBufferSize);
} else {
("Ignore invalid value for receiveBufferSize: " + receiveBufferSize);
}
}
} catch (NumberFormatException nfe) {
("Couldn't parse receiveBufferSize value: " + receiveBufferSizeProperty);
}
// Set SO_SNDBUF write buffer size
String sendBufferSizeProperty = ("sendBufferSize", "-1");
try {
int sendBufferSize = (sendBufferSizeProperty);
if (sendBufferSize > -1) {
if (sendBufferSize > 0) {
().setSendBufferSize(sendBufferSize);
} else {
("Ignore invalid value for sendBufferSize: " + sendBufferSize);
}
}
} catch (NumberFormatException nfe) {
("Couldn't parse sendBufferSize value: " + sendBufferSizeProperty);
}
("Receive Buffer Size is " + ().getReceiveBufferSize());
("Send Buffer Size is " + ().getSendBufferSize());
// Construct and send a startup packet.
String[][] params = {
{ "user", user },
{ "database", database },
{ "client_encoding", "UTF8" },
{ "DateStyle", "ISO" },
{ "extra_float_digits", "2" },
{ "TimeZone", createPostgresTimeZone() },
};
sendStartupPacket(newStream, params, logger);
// Do authentication (until AuthenticationOk).
doAuthentication(newStream, (), user, info, logger);
// Do final startup.
ProtocolConnectionImpl protoConnection = new ProtocolConnectionImpl(newStream, user, database, info, logger, connectTimeout);
readStartupMessages(newStream, protoConnection, logger);
runInitialQueries(protoConnection, info, logger);
// And we're done.
return protoConnection;
}
catch (UnsupportedProtocolException upe)
{
// Swallow this and return null so ConnectionFactory tries the next protocol.
if (())
("Protocol not supported, abandoning connection.");
try
{
();
}
catch (IOException e)
{
}
return null;
}
catch (ConnectException cex)
{
// Added by Peter Mount <peter@>
// ConnectException is thrown when the connection cannot be made.
// we trap this an return a more meaningful message for the end user
if (whichHost + 1 < ) {
// still more addresses to try
continue;
}
throw new PSQLException (("Connection refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections."), PSQLState.CONNECTION_UNABLE_TO_CONNECT, cex);
}
catch (IOException ioe)
{
if (newStream != null)
{
try
{
();
}
catch (IOException e)
{
}
}
if (whichHost + 1 < ) {
// still more addresses to try
continue;
}
throw new PSQLException (("The connection attempt failed."), PSQLState.CONNECTION_UNABLE_TO_CONNECT, ioe);
}
catch (SQLException se)
{
if (newStream != null)
{
try
{
();
}
catch (IOException e)
{
}
}
if (whichHost + 1 < ) {
// still more addresses to try
continue;
}
throw se;
}
}
throw new PSQLException (("The connection url is invalid."), PSQLState.CONNECTION_UNABLE_TO_CONNECT);
}