Skip to content

Commit e009a92

Browse files
committed
Attempt to shut down the connection gracefully in case of a TLS handshake exception
1 parent 33debc6 commit e009a92

File tree

3 files changed

+22
-6
lines changed

3 files changed

+22
-6
lines changed

httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import java.util.concurrent.ConcurrentLinkedQueue;
4343
import java.util.concurrent.atomic.AtomicInteger;
4444

45+
import javax.net.ssl.SSLHandshakeException;
4546
import javax.net.ssl.SSLSession;
4647

4748
import org.apache.hc.core5.concurrent.CancellableDependency;
@@ -698,6 +699,8 @@ public final void onException(final Exception cause) {
698699
final CloseMode closeMode;
699700
if (cause instanceof ConnectionClosedException) {
700701
closeMode = CloseMode.GRACEFUL;
702+
} else if (cause instanceof SSLHandshakeException) {
703+
closeMode = CloseMode.GRACEFUL;
701704
} else if (cause instanceof IOException) {
702705
closeMode = CloseMode.IMMEDIATE;
703706
} else {

httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/AbstractHttp1StreamDuplexer.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.concurrent.atomic.AtomicInteger;
3838
import java.util.concurrent.locks.ReentrantLock;
3939

40+
import javax.net.ssl.SSLHandshakeException;
4041
import javax.net.ssl.SSLSession;
4142

4243
import org.apache.hc.core5.http.ConnectionClosedException;
@@ -166,6 +167,8 @@ void shutdownSession(final Exception cause) {
166167
final CloseMode closeMode;
167168
if (cause instanceof ConnectionClosedException) {
168169
closeMode = CloseMode.GRACEFUL;
170+
} else if (cause instanceof SSLHandshakeException) {
171+
closeMode = CloseMode.GRACEFUL;
169172
} else if (cause instanceof IOException) {
170173
closeMode = CloseMode.IMMEDIATE;
171174
} else {

httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,12 @@ public void exception(final IOSession protocolSession, final Exception cause) {
232232
}
233233
final IOEventHandler handler = session.getHandler();
234234
if (handshakeStateRef.get() != TLSHandShakeState.COMPLETE) {
235-
session.close(CloseMode.GRACEFUL);
236-
close(CloseMode.IMMEDIATE);
235+
if (cause instanceof SSLHandshakeException) {
236+
close(CloseMode.GRACEFUL);
237+
} else {
238+
session.close(CloseMode.GRACEFUL);
239+
close(CloseMode.IMMEDIATE);
240+
}
237241
}
238242
if (handler != null) {
239243
handler.exception(protocolSession, cause);
@@ -467,13 +471,17 @@ private void updateEventMask() {
467471
this.sslEngine.closeOutbound();
468472
this.outboundClosedCount.incrementAndGet();
469473
}
470-
if (this.status == Status.CLOSING && this.sslEngine.isOutboundDone()
474+
final HandshakeStatus handshakeStatus = this.sslEngine.getHandshakeStatus();
475+
if (this.status == Status.CLOSING
476+
&& (handshakeStatus == HandshakeStatus.NOT_HANDSHAKING || handshakeStatus == HandshakeStatus.FINISHED)
477+
&& !this.outEncrypted.hasData()
478+
&& this.sslEngine.isOutboundDone()
471479
&& (this.endOfStream || this.sslEngine.isInboundDone())) {
472480
this.status = Status.CLOSED;
473481
}
474482
// Abnormal session termination
475483
if (this.status.compareTo(Status.CLOSING) <= 0 && this.endOfStream
476-
&& this.sslEngine.getHandshakeStatus() == HandshakeStatus.NEED_UNWRAP) {
484+
&& handshakeStatus == HandshakeStatus.NEED_UNWRAP) {
477485
this.status = Status.CLOSED;
478486
}
479487
if (this.status == Status.CLOSED) {
@@ -484,7 +492,7 @@ private void updateEventMask() {
484492
return;
485493
}
486494
// Is there a task pending?
487-
if (this.sslEngine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
495+
if (handshakeStatus == HandshakeStatus.NEED_TASK) {
488496
doRunTask();
489497
}
490498
// Need to toggle the event mask for this channel?
@@ -527,7 +535,7 @@ private void updateEventMask() {
527535
private int sendEncryptedData() throws IOException {
528536
this.session.getLock().lock();
529537
try {
530-
if (!this.outEncrypted.hasData()) {
538+
if (this.status == Status.ACTIVE && !this.outEncrypted.hasData()) {
531539
// If the buffer isn't acquired or is empty, call write() with an empty buffer.
532540
// This will ensure that tests performed by write() still take place without
533541
// having to acquire and release an empty buffer (e.g. connection closed,
@@ -719,6 +727,8 @@ public void close(final CloseMode closeMode) {
719727
// in the JSSE provider. For instance
720728
// com.android.org.conscrypt.NativeCrypto#SSL_get_shutdown can
721729
// throw NPE at this point
730+
doHandshake(this);
731+
sendEncryptedData();
722732
updateEventMask();
723733
} catch (final CancelledKeyException ex) {
724734
this.session.close(CloseMode.GRACEFUL);

0 commit comments

Comments
 (0)