-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Version
4.5.12
Context
Due to a bad actor in an external network, my team and I have discovered that the configured ProxyHandler (from netty) does not configure the connection timeout when deploying the proxy handler:
The uncalled method setConnectTimeoutMillis
: https://netty.io/4.1/api/io/netty/handler/proxy/ProxyHandler.html#setConnectTimeoutMillis-long-
As far as I know, the ProxyHandler is deployed here in ChannelProvider
:
ProxyHandler proxy; |
Problem
The bad actor will randomly/sometimes take 10 seconds to accept a HTTP connection. (We measured from our side of the proxy. Only this one server, and the connect takes either milliseconds, or 10 seconds plus milliseconds.)
This is unfortunate, because the default timeout in netty is 10 seconds:
This will just as consistently lead to the following exception:
jakarta.ws.rs.ProcessingException: io.netty.handler.proxy.ProxyConnectException: http, basic, /[<IPv6 address>]:7071 => <the bad actor>, timeout
at org.jboss.resteasy.reactive.client.handlers.ClientSendRequestHandler$2.accept(ClientSendRequestHandler.java:225)
at org.jboss.resteasy.reactive.client.handlers.ClientSendRequestHandler$2.accept(ClientSendRequestHandler.java:217)
at io.smallrye.context.impl.wrappers.SlowContextualConsumer.accept(SlowContextualConsumer.java:21)
at io.smallrye.mutiny.helpers.UniCallbackSubscriber.onFailure(UniCallbackSubscriber.java:62)
at io.smallrye.mutiny.operators.uni.UniOperatorProcessor.onFailure(UniOperatorProcessor.java:55)
at org.jboss.resteasy.reactive.client.AsyncResultUni.lambda$subscribe$1(AsyncResultUni.java:37)
at io.vertx.core.impl.future.FutureImpl$4.onFailure(FutureImpl.java:188)
at io.vertx.core.impl.future.FutureBase.lambda$emitFailure$1(FutureBase.java:75)
at io.vertx.core.impl.ContextImpl.execute(ContextImpl.java:312)
at io.vertx.core.impl.DuplicatedContext.execute(DuplicatedContext.java:168)
at io.vertx.core.impl.future.FutureBase.emitFailure(FutureBase.java:72)
at io.vertx.core.impl.future.FutureImpl.tryFail(FutureImpl.java:278)
at io.vertx.core.http.impl.HttpClientImpl.lambda$doRequest$4(HttpClientImpl.java:398)
at io.vertx.core.net.impl.pool.Endpoint.lambda$getConnection$0(Endpoint.java:52)
at io.vertx.core.http.impl.SharedClientHttpStreamEndpoint$Request.handle(SharedClientHttpStreamEndpoint.java:162)
at io.vertx.core.http.impl.SharedClientHttpStreamEndpoint$Request.handle(SharedClientHttpStreamEndpoint.java:123)
at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:342)
at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:335)
at io.vertx.core.net.impl.pool.SimpleConnectionPool$ConnectFailed$1.run(SimpleConnectionPool.java:380)
at io.vertx.core.net.impl.pool.Task.runNextTasks(Task.java:43)
at io.vertx.core.net.impl.pool.CombinerExecutor.submit(CombinerExecutor.java:91)
at io.vertx.core.net.impl.pool.SimpleConnectionPool.execute(SimpleConnectionPool.java:244)
at io.vertx.core.net.impl.pool.SimpleConnectionPool.lambda$connect$2(SimpleConnectionPool.java:258)
at io.vertx.core.http.impl.SharedClientHttpStreamEndpoint.lambda$connect$2(SharedClientHttpStreamEndpoint.java:104)
at io.vertx.core.impl.future.FutureImpl$4.onFailure(FutureImpl.java:188)
at io.vertx.core.impl.future.FutureBase.emitFailure(FutureBase.java:81)
at io.vertx.core.impl.future.FutureImpl.tryFail(FutureImpl.java:278)
at io.vertx.core.impl.future.Composition$1.onFailure(Composition.java:66)
at io.vertx.core.impl.future.FutureBase.emitFailure(FutureBase.java:81)
at io.vertx.core.impl.future.FailedFuture.addListener(FailedFuture.java:98)
at io.vertx.core.impl.future.Composition.onFailure(Composition.java:55)
at io.vertx.core.impl.future.FutureBase.emitFailure(FutureBase.java:81)
at io.vertx.core.impl.future.FutureImpl.tryFail(FutureImpl.java:278)
at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:342)
at io.vertx.core.impl.ContextImpl.emit(ContextImpl.java:335)
at io.vertx.core.net.impl.NetClientImpl.failed(NetClientImpl.java:351)
at io.vertx.core.net.impl.NetClientImpl.lambda$connectInternal2$6(NetClientImpl.java:323)
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:603)
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:570)
at io.netty.util.concurrent.DefaultPromise.notifyListeners(DefaultPromise.java:505)
at io.netty.util.concurrent.DefaultPromise.setValue0(DefaultPromise.java:649)
at io.netty.util.concurrent.DefaultPromise.setFailure0(DefaultPromise.java:642)
at io.netty.util.concurrent.DefaultPromise.setFailure(DefaultPromise.java:123)
at io.vertx.core.net.impl.ChannelProvider$3$1.exceptionCaught(ChannelProvider.java:235)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:346)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:325)
at io.netty.channel.AbstractChannelHandlerContext.fireExceptionCaught(AbstractChannelHandlerContext.java:317)
at io.netty.handler.proxy.ProxyHandler.failPendingWritesAndClose(ProxyHandler.java:356)
at io.netty.handler.proxy.ProxyHandler.setConnectFailure(ProxyHandler.java:349)
at io.netty.handler.proxy.ProxyHandler.access$100(ProxyHandler.java:41)
at io.netty.handler.proxy.ProxyHandler$2.run(ProxyHandler.java:201)
at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98)
at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:156)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:173)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:166)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:998)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: io.netty.handler.proxy.ProxyConnectException: http, basic, /[<IPv6 address>]:7071 => <the bad actor>, timeout
... 11 more
The quarkus default timeout of 15 seconds does not play a role, nor does increasing this value to 30 seconds.
https://quarkus.io/guides/rest-client#quarkus-rest-client-config_quarkus-rest-client-connect-timeout
We believe that this issue could be resolved by respecting and using the connect timeout value of the client.
Steps to reproduce
No response
Do you have a reproducer?
No response