grpc / grpc/grpc-java

"HTTP/1 Only" Support for grpc-java

Open
#9,999 0 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Java
Stars
12.1k
Forks
4k
Avg merge
2d 17h
Merged PRs (30d)
37

Description

### Problem
My Java gRPC server cannot accept HTTP/1 requests as already reported with https://github.com/grpc/grpc-java/issues/4067 because the following exception is thrown:

```
io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2Exception: Unexpected HTTP/1.x request: POST /org.foo.BarService/Check
at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2Exception.connectionError(Http2Exception.java:103)
at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.readClientPrefaceString(Http2ConnectionHandler.java:302)
at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.decode(Http2ConnectionHandler.java:239)
at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:438)
at io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501)
at io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:440)
at io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.grpc.netty.shaded.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.grpc.netty.shaded.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.grpc.netty.shaded.io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:714)
at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:650)
at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:576)
at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.grpc.netty.shaded.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.grpc.netty.shaded.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.grpc.netty.shaded.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:750)
```
(grpc-netty-shaded-1.41.1)

The mentioned issue was closed by @ejona86 in favor of https://github.com/grpc/grpc-java/issues/3458. However, #3458 is about accepting both HTTP/1 and HTTP/2 on the same port which is not my request.

### Request
I want to be able to run a gRPC server that accepts unsecured HTTP/1 requests (_instead_ of HTTP/2 requests). Due to technical restrictions, my clients can only send HTTP/1 requests with JSON bodies.

I plan to implement an interceptor that transcodes JSON strings of given requests to gRPC messages but `ServerInterceptor#interceptCall` is never reached due to the exception above.

### Not Working Workarounds
I also tried to use Nginx with a configuration like this:

```
location ~* /org.foo.BarService*/ {
grpc_pass grpc://172.17.0.1:49209;
grpc_connect_timeout 600s;
grpc_send_timeout 600s;
grpc_read_timeout 600s;
grpc_set_header Host $host;
grpc_set_header X-Real-IP $remote_addr;
grpc_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
grpc_set_header X-Forwarded-Proto $scheme;
grpc_set_header Content-Type application/grpc-web+proto;
grpc_set_header Accept-Encoding identity,gzip;
}
```

but grpc-java doesn't support the "grpc-web+proto" content-type.

### Working Workarounds
I can implement a usual REST server that creates gRPC messages for given JSON strings and forwards them via `io.grpc.inprocess.InProcessServerBuilder`. But since gRPC supports [transcoding](https://cloud.google.com/endpoints/docs/grpc/transcoding#deploying_a_service_that_uses_transcoding) out of the box, I'd like to be able to benefit from this directly (maybe even without having to write an interceptor myself).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.