Skip to content

Commit 3de1621

Browse files
committed
account for padding in flow control, when received frame uses it
1 parent 4acc910 commit 3de1621

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

transport/http2_client.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) {
742742
}
743743

744744
func (t *http2Client) handleData(f *http2.DataFrame) {
745-
size := len(f.Data())
745+
size := f.Header().Length
746746
if err := t.fc.onData(uint32(size)); err != nil {
747747
t.notifyError(connectionErrorf(true, err, "%v", err))
748748
return
@@ -756,6 +756,11 @@ func (t *http2Client) handleData(f *http2.DataFrame) {
756756
return
757757
}
758758
if size > 0 {
759+
if f.Header().Flags.Has(http2.FlagDataPadded) {
760+
if w := t.fc.onRead(uint32(size) - uint32(len(f.Data()))); w > 0 {
761+
t.controlBuf.put(&windowUpdate{0, w})
762+
}
763+
}
759764
s.mu.Lock()
760765
if s.state == streamDone {
761766
s.mu.Unlock()
@@ -775,13 +780,20 @@ func (t *http2Client) handleData(f *http2.DataFrame) {
775780
t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl})
776781
return
777782
}
783+
if f.Header().Flags.Has(http2.FlagDataPadded) {
784+
if w := s.fc.onRead(uint32(size) - uint32(len(f.Data()))); w > 0 {
785+
t.controlBuf.put(&windowUpdate{s.id, w})
786+
}
787+
}
778788
s.mu.Unlock()
779789
// TODO(bradfitz, zhaoq): A copy is required here because there is no
780790
// guarantee f.Data() is consumed before the arrival of next frame.
781791
// Can this copy be eliminated?
782-
data := make([]byte, size)
783-
copy(data, f.Data())
784-
s.write(recvMsg{data: data})
792+
if len(f.Data()) > 0 {
793+
data := make([]byte, len(f.Data()))
794+
copy(data, f.Data())
795+
s.write(recvMsg{data: data})
796+
}
785797
}
786798
// The server has closed the stream without sending trailers. Record that
787799
// the read direction is closed, and set the status appropriately.

transport/http2_server.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ func (t *http2Server) updateWindow(s *Stream, n uint32) {
381381
}
382382

383383
func (t *http2Server) handleData(f *http2.DataFrame) {
384-
size := len(f.Data())
384+
size := f.Header().Length
385385
if err := t.fc.onData(uint32(size)); err != nil {
386386
grpclog.Printf("transport: http2Server %v", err)
387387
t.Close()
@@ -396,6 +396,11 @@ func (t *http2Server) handleData(f *http2.DataFrame) {
396396
return
397397
}
398398
if size > 0 {
399+
if f.Header().Flags.Has(http2.FlagDataPadded) {
400+
if w := t.fc.onRead(uint32(size) - uint32(len(f.Data()))); w > 0 {
401+
t.controlBuf.put(&windowUpdate{0, w})
402+
}
403+
}
399404
s.mu.Lock()
400405
if s.state == streamDone {
401406
s.mu.Unlock()
@@ -411,13 +416,20 @@ func (t *http2Server) handleData(f *http2.DataFrame) {
411416
t.controlBuf.put(&resetStream{s.id, http2.ErrCodeFlowControl})
412417
return
413418
}
419+
if f.Header().Flags.Has(http2.FlagDataPadded) {
420+
if w := s.fc.onRead(uint32(size) - uint32(len(f.Data()))); w > 0 {
421+
t.controlBuf.put(&windowUpdate{s.id, w})
422+
}
423+
}
414424
s.mu.Unlock()
415425
// TODO(bradfitz, zhaoq): A copy is required here because there is no
416426
// guarantee f.Data() is consumed before the arrival of next frame.
417427
// Can this copy be eliminated?
418-
data := make([]byte, size)
419-
copy(data, f.Data())
420-
s.write(recvMsg{data: data})
428+
if len(f.Data()) > 0 {
429+
data := make([]byte, len(f.Data()))
430+
copy(data, f.Data())
431+
s.write(recvMsg{data: data})
432+
}
421433
}
422434
if f.Header().Flags.Has(http2.FlagDataEndStream) {
423435
// Received the end of stream from the client.

0 commit comments

Comments
 (0)