Closed drcrallen closed 2 months ago
I agree, that could use a better message. I'm not even sure where the plaintext is coming from.
@carl-mastrangelo I see this issue now with my application and notice it has been added to the milestone, any thoughts on this?
@vaikzs I'm not sure how this is possible. gRPC always sends HEADERS before data, and we check for a leading slash in NettyServerHandler.onHeadersRead
. There must be some other reason why the stream is not in the property map, because the stream would have been closed before ever getting to onDataRead.
@carl-mastrangelo Thanks for the response. Not noticing this issue anymore, all we did was follow the https://github.com/grpc/grpc-java
to set up the Server instance, only this time with a custom executor and NettyServerBuilder.
After going through the comments/descriptions in the ticket, as per the comments from carl-mastrangelo in the ticket can see a check for path which is missing the leading "/" in onReadHeader() method as below for Headers info in the NettyServerHandler class. As he commented looks like this issue not with missing leading slash as this was caught at the header level check before calling onDataRead() method.
if (path.charAt(0) != '/') { respondWithHttpError(ctx, streamId, 404, Status.Code.UNIMPLEMENTED, String.format("Expected path to start with /: %s", path)); return; }
I also validated/debug this peace of code through JUnit cases (NettyServerHandlerTest.headersWithInvalidPathShouldFail()) and its failing if slash is missing in onReadHeader() method.
Also I can see the comments from vaikzs saying he is not able to see this issue later after following grpc-java setup for server instance.
As per the recent discussion with @kannanjgithub on the latest Analysis, no further action required on this issue.
@kannanjgithub as discussed in the last call are we good to close this ticket?
We can close this for a different reason, but I think @vinodhabib's analysis was incomplete. The stack trace wasn't within onHeadersRead()
; it was within onDataRead()
. The problem was the error handling path as additional frames arrive.
A client could send two frames: HEADERS and DATA. If the processing of the HEADERS fails, the DATA frame will still be arriving; there's a delay after resetting a stream until the remote side learns the stream is reset (and we should even ignore that, as we shouldn't be letting remote machines trigger NPEs).
So let's look back in time at the code throwing a NPE when it was reported: https://github.com/grpc/grpc-java/blob/591a26b1dd5eb0a13c53539da190d6bf8c51bc5b/netty/src/main/java/io/grpc/netty/NettyServerHandler.java#L463-L464
requireHttp2Stream()
handles the case where this is an unknown stream. But serverStream()
might not find gRPC stream information associated with that HTTP/2 stream and so return null
. And looking at the original path handling, it doesn't create any gRPC stream (ditto for many other cases):
https://github.com/grpc/grpc-java/blob/591a26b1dd5eb0a13c53539da190d6bf8c51bc5b/netty/src/main/java/io/grpc/netty/NettyServerHandler.java#L386-L390
But looking at the current code, I do think it is fixed. onDataRead()
now has:
https://github.com/grpc/grpc-java/blob/37d19babffaa91dd3f58f2a9e1c1d774efeb7b98/netty/src/main/java/io/grpc/netty/NettyServerHandler.java#L533-L536
That check was added in https://github.com/grpc/grpc-java/pull/10384 . The other usages of serverStream()
also have null checks.
If a go client initiates a
grpc.ClientConn.NewStream
to a java server, but themethod
passed intoNewStream
is lacking the leading '/
', thenio.netty.handler.codec.http2.DefaultHttp2Connection.DefaultStream
will have anull
property inio.netty.handler.codec.http2.DefaultHttp2Connection.DefaultStream.PropertyMap
, resulting in anull
stream inio.grpc.netty.NettyServerHandler#onDataRead
and aNullPointerException
whenstream.inboundDataReceived(data, endOfStream);
is called.On the server side this yields logs like:
and on the client side the request results in
Adding in the leading
/
on the go client'sNewStream
call fixes the issueWhat version of gRPC are you using?
This is using
netty-codec-http2
version4.1.29.Final
withgrpc-netty
version1.15.0
What did you expect to see?
A more descriptive error that there was something wrong in the request. Neither the server logs nor the client error message is descriptive. It is possible the
text/plain
content might be helpful from the client side, but I couldn't find out where the exception for the content type was coming from in order to fix it.