Skip to content

Commit 048bcc1

Browse files
committed
Protocol negotiation handlers to use exception callback to report unexpected exceptions during the protocol negotiation handshake
1 parent 649c3fc commit 048bcc1

14 files changed

Lines changed: 82 additions & 33 deletions

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
import org.apache.hc.core5.annotation.Internal;
3636
import org.apache.hc.core5.concurrent.FutureCallback;
37+
import org.apache.hc.core5.function.Callback;
3738
import org.apache.hc.core5.http.impl.nio.BufferedData;
3839
import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
3940
import org.apache.hc.core5.reactor.IOSession;
@@ -68,8 +69,9 @@ public class ClientH2PrefaceHandler extends PrefaceHandlerBase {
6869
public ClientH2PrefaceHandler(
6970
final ProtocolIOSession ioSession,
7071
final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory,
71-
final boolean strictALPNHandshake) {
72-
this(ioSession, http2StreamHandlerFactory, strictALPNHandshake, null);
72+
final boolean strictALPNHandshake,
73+
final Callback<Exception> exceptionCallback) {
74+
this(ioSession, http2StreamHandlerFactory, strictALPNHandshake, null, exceptionCallback);
7375
}
7476

7577
/**
@@ -79,8 +81,9 @@ public ClientH2PrefaceHandler(
7981
final ProtocolIOSession ioSession,
8082
final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory,
8183
final boolean strictALPNHandshake,
82-
final FutureCallback<ProtocolIOSession> resultCallback) {
83-
super(ioSession, resultCallback);
84+
final FutureCallback<ProtocolIOSession> resultCallback,
85+
final Callback<Exception> exceptionCallback) {
86+
super(ioSession, resultCallback, exceptionCallback);
8487
this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
8588
this.strictALPNHandshake = strictALPNHandshake;
8689
this.initialized = new AtomicBoolean();

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.hc.core5.annotation.Internal;
3434
import org.apache.hc.core5.annotation.ThreadingBehavior;
3535
import org.apache.hc.core5.concurrent.FutureCallback;
36+
import org.apache.hc.core5.function.Callback;
3637
import org.apache.hc.core5.http.impl.nio.HttpConnectionEventHandler;
3738
import org.apache.hc.core5.reactor.ProtocolIOSession;
3839
import org.apache.hc.core5.reactor.ProtocolUpgradeHandler;
@@ -49,15 +50,18 @@
4950
public class ClientH2UpgradeHandler implements ProtocolUpgradeHandler {
5051

5152
private final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory;
53+
private final Callback<Exception> exceptionCallback;
5254

53-
public ClientH2UpgradeHandler(final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory) {
55+
public ClientH2UpgradeHandler(final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory,
56+
final Callback<Exception> exceptionCallback) {
5457
this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
58+
this.exceptionCallback = exceptionCallback;
5559
}
5660

5761
@Override
5862
public void upgrade(final ProtocolIOSession ioSession, final FutureCallback<ProtocolIOSession> callback) {
5963
final HttpConnectionEventHandler protocolNegotiator = new ClientH2PrefaceHandler(
60-
ioSession, http2StreamHandlerFactory, true, callback);
64+
ioSession, http2StreamHandlerFactory, true, callback, exceptionCallback);
6165
ioSession.upgrade(protocolNegotiator);
6266
try {
6367
protocolNegotiator.connected(ioSession);

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.hc.core5.annotation.Contract;
3131
import org.apache.hc.core5.annotation.Internal;
3232
import org.apache.hc.core5.annotation.ThreadingBehavior;
33+
import org.apache.hc.core5.function.Callback;
3334
import org.apache.hc.core5.http.URIScheme;
3435
import org.apache.hc.core5.http.impl.nio.ClientHttp1IOEventHandler;
3536
import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexerFactory;
@@ -59,18 +60,21 @@ public class ClientHttpProtocolNegotiationStarter implements IOEventHandlerFacto
5960
private final HttpVersionPolicy versionPolicy;
6061
private final TlsStrategy tlsStrategy;
6162
private final Timeout handshakeTimeout;
63+
private final Callback<Exception> exceptionCallback;
6264

6365
public ClientHttpProtocolNegotiationStarter(
6466
final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory,
6567
final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory,
6668
final HttpVersionPolicy versionPolicy,
6769
final TlsStrategy tlsStrategy,
68-
final Timeout handshakeTimeout) {
70+
final Timeout handshakeTimeout,
71+
final Callback<Exception> exceptionCallback) {
6972
this.http1StreamHandlerFactory = Args.notNull(http1StreamHandlerFactory, "HTTP/1.1 stream handler factory");
7073
this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
7174
this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
7275
this.tlsStrategy = tlsStrategy;
7376
this.handshakeTimeout = handshakeTimeout;
77+
this.exceptionCallback = exceptionCallback;
7478
}
7579

7680
@Override
@@ -87,11 +91,11 @@ public HttpConnectionEventHandler createHandler(final ProtocolIOSession ioSessio
8791
}
8892

8993
ioSession.registerProtocol(ApplicationProtocol.HTTP_1_1.id, new ClientHttp1UpgradeHandler(http1StreamHandlerFactory));
90-
ioSession.registerProtocol(ApplicationProtocol.HTTP_2.id, new ClientH2UpgradeHandler(http2StreamHandlerFactory));
94+
ioSession.registerProtocol(ApplicationProtocol.HTTP_2.id, new ClientH2UpgradeHandler(http2StreamHandlerFactory, exceptionCallback));
9195

9296
switch (endpointPolicy) {
9397
case FORCE_HTTP_2:
94-
return new ClientH2PrefaceHandler(ioSession, http2StreamHandlerFactory, false);
98+
return new ClientH2PrefaceHandler(ioSession, http2StreamHandlerFactory, false, exceptionCallback);
9599
case FORCE_HTTP_1:
96100
return new ClientHttp1IOEventHandler(http1StreamHandlerFactory.create(ioSession));
97101
default:

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import javax.net.ssl.SSLSession;
3737

3838
import org.apache.hc.core5.concurrent.FutureCallback;
39+
import org.apache.hc.core5.function.Callback;
3940
import org.apache.hc.core5.http.ConnectionClosedException;
4041
import org.apache.hc.core5.http.EndpointDetails;
4142
import org.apache.hc.core5.http.HttpVersion;
@@ -55,14 +56,17 @@ abstract class PrefaceHandlerBase implements HttpConnectionEventHandler {
5556
final ProtocolIOSession ioSession;
5657
private final AtomicReference<HttpConnectionEventHandler> protocolHandlerRef;
5758
private final FutureCallback<ProtocolIOSession> resultCallback;
59+
private final Callback<Exception> exceptionCallback;
5860
private final AtomicBoolean completed;
5961

6062
PrefaceHandlerBase(
6163
final ProtocolIOSession ioSession,
62-
final FutureCallback<ProtocolIOSession> resultCallback) {
64+
final FutureCallback<ProtocolIOSession> resultCallback,
65+
final Callback<Exception> exceptionCallback) {
6366
this.ioSession = Args.notNull(ioSession, "I/O session");
6467
this.protocolHandlerRef = new AtomicReference<>();
6568
this.resultCallback = resultCallback;
69+
this.exceptionCallback = exceptionCallback;
6670
this.completed = new AtomicBoolean();
6771
}
6872

@@ -92,11 +96,17 @@ public void exception(final IOSession session, final Exception cause) {
9296
protocolHandler.exception(session, cause);
9397
} else {
9498
CommandSupport.failCommands(session, cause);
99+
if (exceptionCallback != null) {
100+
exceptionCallback.execute(cause);
101+
}
95102
}
96103
} catch (final Exception ex) {
97104
if (completed.compareAndSet(false, true) && resultCallback != null) {
98105
resultCallback.failed(ex);
99106
}
107+
if (exceptionCallback != null) {
108+
exceptionCallback.execute(cause);
109+
}
100110
}
101111
}
102112

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import org.apache.hc.core5.annotation.Internal;
3434
import org.apache.hc.core5.concurrent.FutureCallback;
35+
import org.apache.hc.core5.function.Callback;
3536
import org.apache.hc.core5.http.ConnectionClosedException;
3637
import org.apache.hc.core5.http.impl.nio.BufferedData;
3738
import org.apache.hc.core5.reactor.IOSession;
@@ -54,15 +55,17 @@ public class ServerH2PrefaceHandler extends PrefaceHandlerBase {
5455

5556
public ServerH2PrefaceHandler(
5657
final ProtocolIOSession ioSession,
57-
final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory) {
58-
this(ioSession, http2StreamHandlerFactory, null);
58+
final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory,
59+
final Callback<Exception> exceptionCallback) {
60+
this(ioSession, http2StreamHandlerFactory, null, exceptionCallback);
5961
}
6062

6163
public ServerH2PrefaceHandler(
6264
final ProtocolIOSession ioSession,
6365
final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory,
64-
final FutureCallback<ProtocolIOSession> resultCallback) {
65-
super(ioSession, resultCallback);
66+
final FutureCallback<ProtocolIOSession> resultCallback,
67+
final Callback<Exception> exceptionCallback) {
68+
super(ioSession, resultCallback, exceptionCallback);
6669
this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
6770
this.inBuf = BufferedData.allocate(1024);
6871
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.apache.hc.core5.annotation.Internal;
3434
import org.apache.hc.core5.annotation.ThreadingBehavior;
3535
import org.apache.hc.core5.concurrent.FutureCallback;
36+
import org.apache.hc.core5.function.Callback;
3637
import org.apache.hc.core5.http.impl.nio.HttpConnectionEventHandler;
3738
import org.apache.hc.core5.reactor.ProtocolIOSession;
3839
import org.apache.hc.core5.reactor.ProtocolUpgradeHandler;
@@ -49,15 +50,18 @@
4950
public class ServerH2UpgradeHandler implements ProtocolUpgradeHandler {
5051

5152
private final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory;
53+
private final Callback<Exception> exceptionCallback;
5254

53-
public ServerH2UpgradeHandler(final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory) {
55+
public ServerH2UpgradeHandler(final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory,
56+
final Callback<Exception> exceptionCallback) {
5457
this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
58+
this.exceptionCallback = exceptionCallback;
5559
}
5660

5761
@Override
5862
public void upgrade(final ProtocolIOSession ioSession, final FutureCallback<ProtocolIOSession> callback) {
5963
final HttpConnectionEventHandler protocolNegotiator = new ServerH2PrefaceHandler(
60-
ioSession, http2StreamHandlerFactory, callback);
64+
ioSession, http2StreamHandlerFactory, callback, exceptionCallback);
6165
ioSession.upgrade(protocolNegotiator);
6266
try {
6367
protocolNegotiator.connected(ioSession);

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.apache.hc.core5.annotation.Contract;
3131
import org.apache.hc.core5.annotation.Internal;
3232
import org.apache.hc.core5.annotation.ThreadingBehavior;
33+
import org.apache.hc.core5.function.Callback;
3334
import org.apache.hc.core5.http.URIScheme;
3435
import org.apache.hc.core5.http.impl.nio.HttpConnectionEventHandler;
3536
import org.apache.hc.core5.http.impl.nio.ServerHttp1IOEventHandler;
@@ -59,18 +60,21 @@ public class ServerHttpProtocolNegotiationStarter implements IOEventHandlerFacto
5960
private final HttpVersionPolicy versionPolicy;
6061
private final TlsStrategy tlsStrategy;
6162
private final Timeout handshakeTimeout;
63+
private final Callback<Exception> exceptionCallback;
6264

6365
public ServerHttpProtocolNegotiationStarter(
6466
final ServerHttp1StreamDuplexerFactory http1StreamHandlerFactory,
6567
final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory,
6668
final HttpVersionPolicy versionPolicy,
6769
final TlsStrategy tlsStrategy,
68-
final Timeout handshakeTimeout) {
70+
final Timeout handshakeTimeout,
71+
final Callback<Exception> exceptionCallback) {
6972
this.http1StreamHandlerFactory = Args.notNull(http1StreamHandlerFactory, "HTTP/1.1 stream handler factory");
7073
this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
7174
this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
7275
this.tlsStrategy = tlsStrategy;
7376
this.handshakeTimeout = handshakeTimeout;
77+
this.exceptionCallback = exceptionCallback;
7478
}
7579

7680
@Override
@@ -88,12 +92,14 @@ public HttpConnectionEventHandler createHandler(final ProtocolIOSession ioSessio
8892
}
8993
}
9094

91-
ioSession.registerProtocol(ApplicationProtocol.HTTP_1_1.id, new ServerHttp1UpgradeHandler(http1StreamHandlerFactory));
92-
ioSession.registerProtocol(ApplicationProtocol.HTTP_2.id, new ServerH2UpgradeHandler(http2StreamHandlerFactory));
95+
ioSession.registerProtocol(ApplicationProtocol.HTTP_1_1.id,
96+
new ServerHttp1UpgradeHandler(http1StreamHandlerFactory));
97+
ioSession.registerProtocol(ApplicationProtocol.HTTP_2.id,
98+
new ServerH2UpgradeHandler(http2StreamHandlerFactory, exceptionCallback));
9399

94100
switch (endpointPolicy) {
95101
case FORCE_HTTP_2:
96-
return new ServerH2PrefaceHandler(ioSession, http2StreamHandlerFactory);
102+
return new ServerH2PrefaceHandler(ioSession, http2StreamHandlerFactory, exceptionCallback);
97103
case FORCE_HTTP_1:
98104
return new ServerHttp1IOEventHandler(http1StreamHandlerFactory.create(uriScheme.id, ioSession));
99105
default:

‎httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequesterBootstrap.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,8 @@ public H2MultiplexingRequester create() {
238238
streamListener);
239239
return new H2MultiplexingRequester(
240240
ioReactorConfig,
241-
(ioSession, attachment) -> new ClientH2PrefaceHandler(ioSession, http2StreamHandlerFactory, strictALPNHandshake),
241+
(ioSession, attachment) ->
242+
new ClientH2PrefaceHandler(ioSession, http2StreamHandlerFactory, strictALPNHandshake, exceptionCallback),
242243
ioSessionDecorator,
243244
exceptionCallback,
244245
sessionListener,

‎httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,8 @@ public H2AsyncRequester create() {
382382
http2StreamHandlerFactory,
383383
versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
384384
actualTlsStrategy,
385-
handshakeTimeout);
385+
handshakeTimeout,
386+
exceptionCallback);
386387

387388
return new H2AsyncRequester(
388389
versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,

‎httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,8 @@ public HttpAsyncServer create() {
520520
http2StreamHandlerFactory,
521521
versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
522522
actualTlsStrategy,
523-
handshakeTimeout);
523+
handshakeTimeout,
524+
exceptionCallback);
524525

525526
return new HttpAsyncServer(ioEventHandlerFactory, ioReactorConfig, ioSessionDecorator, exceptionCallback,
526527
sessionListener, actualCanonicalHostName);

0 commit comments

Comments
 (0)