Spring-cloud-gateway: Support http2

Created on 7 Jan 2017  路  36Comments  路  Source: spring-cloud/spring-cloud-gateway

enhancement

Most helpful comment

reactor-netty has officially distributed v1.0. (relase note link)

reactor-netty v1.0 supports http/2

Now, it's time for Spring-cloud-gateway to support http/2 .

All 36 comments

I believe this is blocked by reactor-netty (@smaldini is that correct?) on the one side and #145 on the other.

still no support for http2, right ?

we are waiting on reactor-netty 0.8 which is in progress.

Once reactor-netty 0.8 is released, will it be enough to update netty dependency version?

no, there will need to be a corresponding gateway release.

Hi, thanks for the quick response.
And do we know how long would it take once the reactor-netty release is available to have, at least, an RC with HTTP 2 in the gateway?

No, I'm afraid not

@spencergibb
Do gateway now support HTTP2?I don't have the documentation, or the plan?

I see that reactor netty has already released a version that supports HTTP2, so which version of the gateway is available?

It has not

Why was the issue closed?

Any plans to implement HTTP2 soon?

It is all based on reactor Netty

What does that mean?This is still blocked by reactor netty, right?

Yes, it is blocked by reactor Netty

I didn't think you'd need client side support of Netty for HTTP/2.

Any news on this? HTTP2 support is now enabled on serverside by netty.

Hello,
Do you know when we can expect HTTP2 support?

Hello,

Cheering for you here. Any update?
Just saying, but our team refactored 20+ micro services from Webflux http to Webflux http2 + https with ssl.

Then, we started to refactor our gateway service, which is in front of our 20+ micro services, to realize http2 is not possible :'D

Thank you!

Any updates on this? I'm so interested in this.

No, when there are updates you will see them here.

Hi,

I am also waiting to know when HTTP2 will be supported on SCG. Any plans for the same?

No change from my comment above

@spencergibb I understand this is blocked by reactor-netty clientside http2 support - but how It would be prioritized if technical blocker goes away? Is It still on roadmap? Will http2 streams be supported end-to-end, or GRPC only - to be on par with standalone proxies (nginx, kong, haproxy have this for few years) and meshes out there.

It's high on the list once the blocker goes away. It will be http2 specific, no subprotocols (ie grpc).

https://github.com/reactor/reactor-netty/pull/1147, that promised HTTP/2 support, was merged today. But there is a new issue for enhancements, not sure if needed here : https://github.com/reactor/reactor-netty/issues/1169

@spencergibb FYI: Without knowing about this issue, I just tried to enable http2 on spring cloud gateway (server.http2.enabled=true). It seemed not too bad. However, the x-http2-scheme=[https] header was ignored and thus spring security's OAUTH implementation didn't work, since gateway rewrote all requests to http. Thus, redirect_uri check failed, plus downstream requests where also rewritten to http and hence SSL verification failed downstream.

reactor-netty has officially distributed v1.0. (relase note link)

reactor-netty v1.0 supports http/2

Now, it's time for Spring-cloud-gateway to support http/2 .

@violetagg anything gateway needs to do specifically to support http2 in gateway with http client?

@spencergibb I found this documentation in the reactor-netty documentation that describes how to use http2 with NettyWebServer and with HttpClient

I'm well aware. It's spring boot that needs to support it. I can't remember if that is in place

Looks like this is all unblocked now https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-configure-http2-netty

@spencergibb tried enabling HTTP2 in my gateway application. Whenever I attempt to route a gRPC call through the gateway I'm getting the following exception:

java.lang.UnsupportedOperationException: unsupported message type: DefaultHttpRequest (expected: ByteBuf, FileRegion)
    at io.netty.channel.nio.AbstractNioByteChannel.filterOutboundMessage(AbstractNioByteChannel.java:286)
    at io.netty.channel.AbstractChannel$AbstractUnsafe.write(AbstractChannel.java:878)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.write(DefaultChannelPipeline.java:1367)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite(AbstractChannelHandlerContext.java:709)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:792)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:702)
    at io.netty.handler.logging.LoggingHandler.write(LoggingHandler.java:279)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717)
    at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:764)
    at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:790)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:758)
    at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:808)
    at io.netty.channel.DefaultChannelPipeline.writeAndFlush(DefaultChannelPipeline.java:1025)
    at io.netty.channel.AbstractChannel.writeAndFlush(AbstractChannel.java:294)
    at reactor.netty.http.HttpOperations.lambda$then$2(HttpOperations.java:200)
    at reactor.netty.FutureMono$DeferredFutureMono.subscribe(FutureMono.java:114)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4213)
    at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:172)
    at reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4213)
    at reactor.netty.NettyOutbound.subscribe(NettyOutbound.java:336)
    at reactor.core.publisher.MonoSource.subscribe(MonoSource.java:65)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.netty.http.client.HttpClientConnect$HttpIOHandlerObserver.onStateChange(HttpClientConnect.java:446)
    at reactor.netty.ReactorNetty$CompositeConnectionObserver.onStateChange(ReactorNetty.java:518)
    at reactor.netty.resources.PooledConnectionProvider$DisposableAcquire.onStateChange(PooledConnectionProvider.java:561)
    at reactor.netty.resources.PooledConnectionProvider$PooledConnection.onStateChange(PooledConnectionProvider.java:448)
    at reactor.netty.channel.ChannelOperationsHandler.channelActive(ChannelOperationsHandler.java:65)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:230)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:216)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelActive(AbstractChannelHandlerContext.java:209)
    at io.netty.handler.logging.LoggingHandler.channelActive(LoggingHandler.java:189)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:230)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:216)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelActive(AbstractChannelHandlerContext.java:209)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelActive(DefaultChannelPipeline.java:1398)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:230)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelActive(AbstractChannelHandlerContext.java:216)
    at io.netty.channel.DefaultChannelPipeline.fireChannelActive(DefaultChannelPipeline.java:895)
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.fulfillConnectPromise(AbstractNioChannel.java:305)
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:335)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:707)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    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:834)

Is there extra work that is required to enable this or should setting the protocol in the NettyServerCustomizer and the HttpClientCustomizer be enough?

I don't know

Was this page helpful?
0 / 5 - 0 ratings