Reactor-netty: HttpClient configured with h2c and http11 protocols fails to work with server that supports only http11

Created on 15 Mar 2021  路  3Comments  路  Source: reactor/reactor-netty


Expected Behavior


HttpClient configured with h2c and http11 protocols can work with servers that don't support h2c and use http11 instead.

Actual Behavior

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.

Steps to Reproduce

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)

Environment


  • Reactor version(s) used: io.projectreactor.netty:reactor-netty:1.0.4
  • JVM version: openjdk-14.0.1-1
  • OS and version: Ubuntu 5.4.0-66-generic
typbug

All 3 comments

@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!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

izeye picture izeye  路  3Comments

vchekan picture vchekan  路  8Comments

violetagg picture violetagg  路  4Comments

be-hase picture be-hase  路  6Comments

violetagg picture violetagg  路  8Comments