aboutsummaryrefslogtreecommitdiff
path: root/src/io
diff options
context:
space:
mode:
authorJorropo <jorropo.pgm@gmail.com>2022-05-02 11:50:36 +0000
committerGopher Robot <gobot@golang.org>2022-05-03 14:37:48 +0000
commit0537a74b76fcab1398da6699c3ff7411fef8fbe7 (patch)
tree063cd4278c88d0e9d2207fc0f2c5a2b67f809376 /src/io
parentd0cda4d95f4c889fdb4988750f704604553c35a4 (diff)
downloadgo-0537a74b76fcab1398da6699c3ff7411fef8fbe7.tar.xz
io: NopCloser forward WriterTo implementations if the reader supports it
This patch also include related fixes to net/http. io_test.go don't test reading or WritingTo of the because the logic is simple. NopCloser didn't even had direct tests before. Fixes #51566 Change-Id: I1943ee2c20d0fe749f4d04177342ce6eca443efe GitHub-Last-Rev: a6b9af4e945a6903735a74aa185e2d1c4c2e2cef GitHub-Pull-Request: golang/go#52340 Reviewed-on: https://go-review.googlesource.com/c/go/+/400236 Run-TryBot: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Benny Siegert <bsiegert@gmail.com> Auto-Submit: Ian Lance Taylor <iant@google.com>
Diffstat (limited to 'src/io')
-rw-r--r--src/io/io.go15
-rw-r--r--src/io/io_test.go21
2 files changed, 36 insertions, 0 deletions
diff --git a/src/io/io.go b/src/io/io.go
index 1ea01d5d63..db88125f50 100644
--- a/src/io/io.go
+++ b/src/io/io.go
@@ -621,7 +621,12 @@ func (discard) ReadFrom(r Reader) (n int64, err error) {
// NopCloser returns a ReadCloser with a no-op Close method wrapping
// the provided Reader r.
+// If r implements WriterTo, the returned ReadCloser will implement WriterTo
+// by forwarding calls to r.
func NopCloser(r Reader) ReadCloser {
+ if _, ok := r.(WriterTo); ok {
+ return nopCloserWriterTo{r}
+ }
return nopCloser{r}
}
@@ -631,6 +636,16 @@ type nopCloser struct {
func (nopCloser) Close() error { return nil }
+type nopCloserWriterTo struct {
+ Reader
+}
+
+func (nopCloserWriterTo) Close() error { return nil }
+
+func (c nopCloserWriterTo) WriteTo(w Writer) (n int64, err error) {
+ return c.Reader.(WriterTo).WriteTo(w)
+}
+
// ReadAll reads from r until an error or EOF and returns the data it read.
// A successful call returns err == nil, not err == EOF. Because ReadAll is
// defined to read from src until EOF, it does not treat an EOF from Read
diff --git a/src/io/io_test.go b/src/io/io_test.go
index 3088460480..a51a1fa160 100644
--- a/src/io/io_test.go
+++ b/src/io/io_test.go
@@ -471,3 +471,24 @@ func TestCopyLargeWriter(t *testing.T) {
t.Errorf("Copy error: got %v, want %v", err, want)
}
}
+
+func TestNopCloserWriterToForwarding(t *testing.T) {
+ for _, tc := range [...]struct {
+ Name string
+ r Reader
+ }{
+ {"not a WriterTo", Reader(nil)},
+ {"a WriterTo", struct {
+ Reader
+ WriterTo
+ }{}},
+ } {
+ nc := NopCloser(tc.r)
+
+ _, expected := tc.r.(WriterTo)
+ _, got := nc.(WriterTo)
+ if expected != got {
+ t.Errorf("NopCloser incorrectly forwards WriterTo for %s, got %t want %t", tc.Name, got, expected)
+ }
+ }
+}