HttpClient configured with h2c and http11 protocols can work with servers that don't support h2c and use http11 instead.
When HttpClient configured to support both h2c and http11 it failed when requesting a server that doesn't support h2c (first two requests complete normally, but 3rd - failed) with java.lang.IllegalStateException: Http2MultiplexCodec or Http2MultiplexHandler must be in the ChannelPipeline of Channel.
The same behavior repeats when HttpClient in Spring Cloud Gateway configured to support both http11 and h2c protocols if a backend service to which request is routed to only supports http11.
Sample project https://github.com/anh-dev/reactor-netty-demo/archive/master.zip
Exception in thread "main" java.lang.IllegalStateException: Http2MultiplexCodec or Http2MultiplexHandler must be in the
ChannelPipeline of Channel [id: 0xa982d924, L:/[0:0:0:0:0:0:0:1%0]:37570 - R:0:0:0:0:0:0:0:1/[0:0:0:0:0:0:0:1]:8888]
at io.netty.handler.codec.http2.Http2StreamChannelBootstrap.findCtx(Http2StreamChannelBootstrap.java:155)
at io.netty.handler.codec.http2.Http2StreamChannelBootstrap.open(Http2StreamChannelBootstrap.java:118)
at io.netty.handler.codec.http2.Http2StreamChannelBootstrap.open(Http2StreamChannelBootstrap.java:108)
at reactor.netty.http.client.HttpClientConfig.openStream(HttpClientConfig.java:597)
at reactor.netty.http.client.Http2ConnectionProvider$DisposableAcquire.onNext(Http2ConnectionProvider.java:269)
at reactor.netty.http.client.Http2ConnectionProvider$DisposableAcquire.onNext(Http2ConnectionProvider.java:171)
at reactor.netty.internal.shaded.reactor.pool.AbstractPool$Borrower.deliver(AbstractPool.java:419)
at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool.lambda$drainLoop$5(SimpleDequePool.java:302)
at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onNext(FluxDoOnEach.java:154)
at reactor.core.publisher.FluxMap$MapConditionalSubscriber.onNext(FluxMap.java:220)
at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:160)
at reactor.netty.resources.DefaultPooledConnectionProvider$DisposableAcquire.run(DefaultPooledConnectionProvider.java:284)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472)
at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:384)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
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:832)
Suppressed: java.lang.Exception: #block terminated with an error
at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:99)
at reactor.core.publisher.Mono.block(Mono.java:1703)
at Main.main(Main.java:29)
@anh-dev Thanks a lot for the reproducible example! If you are able to test PR #1553, it will be great.
@violetagg Checked with Spring Cloud Gateway, it works great! Many thanks for the prompt reply!
@anh-dev Thanks a lot for the testing!