Skip to content

Commit

Permalink
x/net/http2: gzipReader will reset zr to nil after closing body
Browse files Browse the repository at this point in the history
The existing implementation does not reset gz.zr. After Close,
gzipReader closes underlying response body but buffered data can still
be read.

gzipReader on Close sets the gz.zerr to fs.ErrClosed so next Read after
Close will return it immediately.

Fixes golang/go#56020

Change-Id: I8a31e4c65656b9abc3023855b8e04342e1e77cbb
Reviewed-on: https://go-review.googlesource.com/c/net/+/440555
Reviewed-by: Damien Neil <[email protected]>
Run-TryBot: Damien Neil <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Reviewed-by: Than McIntosh <[email protected]>
  • Loading branch information
nikola-jokic authored and neild committed Nov 4, 2022
1 parent a1278a7 commit 7a67682
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
7 changes: 6 additions & 1 deletion http2/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"errors"
"fmt"
"io"
"io/fs"
"log"
"math"
mathrand "math/rand"
Expand Down Expand Up @@ -2985,7 +2986,11 @@ func (gz *gzipReader) Read(p []byte) (n int, err error) {
}

func (gz *gzipReader) Close() error {
return gz.body.Close()
if err := gz.body.Close(); err != nil {
return err
}
gz.zerr = fs.ErrClosed
return nil
}

type errorReader struct{ err error }
Expand Down
24 changes: 24 additions & 0 deletions http2/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ package http2
import (
"bufio"
"bytes"
"compress/gzip"
"context"
"crypto/tls"
"encoding/hex"
"errors"
"flag"
"fmt"
"io"
"io/fs"
"io/ioutil"
"log"
"math/rand"
Expand Down Expand Up @@ -2503,6 +2505,28 @@ func TestGzipReader_DoubleReadCrash(t *testing.T) {
}
}

func TestGzipReader_ReadAfterClose(t *testing.T) {
body := bytes.Buffer{}
w := gzip.NewWriter(&body)
w.Write([]byte("012345679"))
w.Close()
gz := &gzipReader{
body: ioutil.NopCloser(&body),
}
var buf [1]byte
n, err := gz.Read(buf[:])
if n != 1 || err != nil {
t.Fatalf("first Read = %v, %v; want 1, nil", n, err)
}
if err := gz.Close(); err != nil {
t.Fatalf("gz Close error: %v", err)
}
n, err = gz.Read(buf[:])
if n != 0 || err != fs.ErrClosed {
t.Fatalf("Read after close = %v, %v; want 0, fs.ErrClosed", n, err)
}
}

func TestTransportNewTLSConfig(t *testing.T) {
tests := [...]struct {
conf *tls.Config
Expand Down

0 comments on commit 7a67682

Please sign in to comment.