func (t *http2Client) handleData(f *http2.DataFrame) { // Select the right stream to dispatch. s, ok := t.getStream(f) if !ok { return } size := len(f.Data()) if size > 0 { if err := s.fc.onData(uint32(size)); err != nil { if _, ok := err.(ConnectionError); ok { t.notifyError(err) return } s.mu.Lock() if s.state == streamDone { s.mu.Unlock() return } s.state = streamDone s.statusCode = codes.Internal s.statusDesc = err.Error() s.mu.Unlock() s.write(recvMsg{err: io.EOF}) t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl}) return } // TODO(bradfitz, zhaoq): A copy is required here because there is no // guarantee f.Data() is consumed before the arrival of next frame. // Can this copy be eliminated? data := make([]byte, size) copy(data, f.Data()) s.write(recvMsg{data: data}) } // The server has closed the stream without sending trailers. Record that // the read direction is closed, and set the status appropriately. if f.FrameHeader.Flags.Has(http2.FlagDataEndStream) { s.mu.Lock() if s.state == streamWriteDone { s.state = streamDone } else { s.state = streamReadDone } s.statusCode = codes.Internal s.statusDesc = "server closed the stream without sending trailers" s.mu.Unlock() s.write(recvMsg{err: io.EOF}) } }
func (t *http2Server) handleData(f *http2.DataFrame) { // Select the right stream to dispatch. s, ok := t.getStream(f) if !ok { return } size := len(f.Data()) if size > 0 { if err := s.fc.onData(uint32(size)); err != nil { if _, ok := err.(ConnectionError); ok { grpclog.Printf("transport: http2Server %v", err) t.Close() return } t.closeStream(s) t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl}) return } // TODO(bradfitz, zhaoq): A copy is required here because there is no // guarantee f.Data() is consumed before the arrival of next frame. // Can this copy be eliminated? data := make([]byte, size) copy(data, f.Data()) s.write(recvMsg{data: data}) } if f.Header().Flags.Has(http2.FlagDataEndStream) { // Received the end of stream from the client. s.mu.Lock() if s.state != streamDone { if s.state == streamWriteDone { s.state = streamDone } else { s.state = streamReadDone } } s.mu.Unlock() s.write(recvMsg{err: io.EOF}) } }