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}) } }