grpc / grpc/grpc-java

"HTTP/1 Only" Support for grpc-java

Đang mở
#9,999 0 bình luận 0 reaction 0 người được giao Xem trên GitHub
enhancement
Ngôn ngữ chính
Java
Star
12.1k
Fork
4k
Merge trung bình
2 ngày 17 giờ
Pull request đã merge (30 ngày)
37

Mô tả

### 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).

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Hướng nghiên cứu

Bắt đầu bằng cách đọc các issue #4067 và #3458 của grpc-java, sau đó kiểm tra đường đi ServerInterceptor#interceptCall và phần xử lý HTTP/2 khiến đường đi này không thể được gọi tới. So sánh hành vi JSON không bảo mật, chỉ dành cho HTTP/1 được yêu cầu, với workaround InProcessServerBuilder hiện có. Công việc được xem là hoàn tất khi một server có thể chấp nhận các request này và cung cấp một đường dẫn validation được định nghĩa, kèm coverage cho định dạng request được hỗ trợ.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
grpc, java
Lĩnh vực
api, backend
Loại issue
Tính năng
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
25/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.