@@ -322,8 +322,24 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport,
322322 go func () {
323323 t .loopy = newLoopyWriter (serverSide , t .framer , t .controlBuf , t .bdpEst , t .conn , t .logger )
324324 t .loopy .ssGoAwayHandler = t .outgoingGoAwayHandler
325- t .loopy .run ()
325+ err := t .loopy .run ()
326326 close (t .loopyWriterDone )
327+ if ! isIOError (err ) {
328+ // Close the connection if a non-I/O error occurs (for I/O errors
329+ // the reader will also encounter the error and close). Wait 1
330+ // second before closing the connection, or when the reader is done
331+ // (i.e. the client already closed the connection or a connection
332+ // error occurred). This avoids the potential problem where there
333+ // is unread data on the receive side of the connection, which, if
334+ // closed, would lead to a TCP RST instead of FIN, and the client
335+ // encountering errors. For more info:
336+ // https://github.com/grpc/grpc-go/issues/5358
337+ select {
338+ case <- t .readerDone :
339+ case <- time .After (time .Second ):
340+ }
341+ t .conn .Close ()
342+ }
327343 }()
328344 go t .keepalive ()
329345 return t , nil
@@ -609,8 +625,8 @@ func (t *http2Server) operateHeaders(ctx context.Context, frame *http2.MetaHeade
609625// traceCtx attaches trace to ctx and returns the new context.
610626func (t * http2Server ) HandleStreams (ctx context.Context , handle func (* Stream )) {
611627 defer func () {
612- <- t .loopyWriterDone
613628 close (t .readerDone )
629+ <- t .loopyWriterDone
614630 }()
615631 for {
616632 t .controlBuf .throttle ()
@@ -1325,6 +1341,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) {
13251341 if err := t .framer .fr .WriteGoAway (sid , g .code , g .debugData ); err != nil {
13261342 return false , err
13271343 }
1344+ t .framer .writer .Flush ()
13281345 if retErr != nil {
13291346 return false , retErr
13301347 }
@@ -1345,7 +1362,7 @@ func (t *http2Server) outgoingGoAwayHandler(g *goAway) (bool, error) {
13451362 return false , err
13461363 }
13471364 go func () {
1348- timer := time .NewTimer (time .Minute )
1365+ timer := time .NewTimer (5 * time .Second )
13491366 defer timer .Stop ()
13501367 select {
13511368 case <- t .drainEvent .Done ():
0 commit comments