in src/main/java/com/google/cloud/spanner/pgadapter/ConnectionHandler.java [392:497]
private RunConnectionState runConnection(boolean ssl) {
RunConnectionState result = RunConnectionState.TERMINATED;
try (ConnectionMetadata connectionMetadata =
new ConnectionMetadata(this.socket.getInputStream(), this.socket.getOutputStream())) {
this.connectionMetadata = connectionMetadata;
try {
this.message = this.server.recordMessage(BootstrapMessage.create(this));
} catch (EOFException ignore) {
// Just ignore the connection and close it if the client never sends us a valid startup
// message. This also prevents probers that just check for an open TCP port to cause errors
// to be logged.
return result;
} catch (Exception exception) {
this.handleError(
PGException.newBuilder(exception)
.setSeverity(Severity.FATAL)
.setSQLState(SQLState.InternalError)
.build());
throw exception;
}
try {
if (!ssl
&& getServer().getOptions().getSslMode().isSslEnabled()
&& this.message instanceof SSLMessage) {
this.message.send();
this.connectionMetadata.markForRestart();
result = RunConnectionState.RESTART_WITH_SSL;
return result;
}
// Check whether the connection is valid. That is, the connection satisfies any restrictions
// on non-localhost connections and SSL requirements.
if (!checkValidConnection(ssl)) {
return result;
}
this.message.send();
while (this.status == ConnectionStatus.UNAUTHENTICATED) {
try {
message.nextHandler();
message.send();
} catch (EOFException eofException) {
// This indicates that the frontend terminated the connection before we got
// authenticated. This is in most cases an indication that the frontend killed the
// connection after having requested SSL and gotten an SSL denied message.
this.status = ConnectionStatus.TERMINATED;
break;
}
}
while (this.status != ConnectionStatus.TERMINATED) {
handleMessages();
}
} catch (PGException pgException) {
this.handleError(pgException);
} catch (Exception exception) {
this.handleError(
PGException.newBuilder(exception)
.setSeverity(Severity.FATAL)
.setSQLState(SQLState.InternalError)
.build());
}
} catch (Exception e) {
logger.log(
Level.WARNING,
e,
() ->
String.format(
"Exception on connection handler with ID %s for client %s: %s",
getName(),
socket == null || socket.getInetAddress() == null
? "(none)"
: socket.getInetAddress().getHostAddress(),
e));
} finally {
if (result != RunConnectionState.RESTART_WITH_SSL) {
logger.log(
Level.INFO,
Logging.format(
"RunConnection",
() -> String.format("Closing connection handler with ID %s", getName())));
try {
if (this.spannerConnection != null) {
this.spannerConnection.close();
}
this.socket.close();
} catch (SpannerException | IOException e) {
logger.log(
Level.WARNING,
e,
Logging.format(
"RunConnection",
() ->
String.format(
"Exception while closing connection handler with ID %s", getName())));
} finally {
this.server.deregister(this);
logger.log(
Level.INFO,
Logging.format(
"RunConnection",
() -> String.format("Connection handler with ID %s closed", getName())));
}
}
}
return result;
}