Skip to content

Commit 201a2e9

Browse files
compress/gzip: add example of compressing reader
For #51092 Change-Id: If0a233651ac75f113569ddfffd056084f6092564 Reviewed-on: https://go-review.googlesource.com/c/go/+/389514 Trust: Ian Lance Taylor <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]> Reviewed-by: Joseph Tsai <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 4e26ab0 commit 201a2e9

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

src/compress/gzip/example_test.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ import (
1010
"fmt"
1111
"io"
1212
"log"
13+
"net/http"
14+
"net/http/httptest"
1315
"os"
16+
"strings"
1417
"time"
1518
)
1619

@@ -126,3 +129,87 @@ func ExampleReader_Multistream() {
126129
//
127130
// Hello Gophers - 2
128131
}
132+
133+
func Example_compressingReader() {
134+
// This is an example of writing a compressing reader.
135+
// This can be useful for an HTTP client body, as shown.
136+
137+
const testdata = "the data to be compressed"
138+
139+
// This HTTP handler is just for testing purposes.
140+
handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
141+
zr, err := gzip.NewReader(req.Body)
142+
if err != nil {
143+
log.Fatal(err)
144+
}
145+
146+
// Just output the data for the example.
147+
if _, err := io.Copy(os.Stdout, zr); err != nil {
148+
log.Fatal(err)
149+
}
150+
})
151+
ts := httptest.NewServer(handler)
152+
defer ts.Close()
153+
154+
// The remainder is the example code.
155+
156+
// The data we want to compress, as an io.Reader
157+
dataReader := strings.NewReader(testdata)
158+
159+
// bodyReader is the body of the HTTP request, as an io.Reader.
160+
// httpWriter is the body of the HTTP request, as an io.Writer.
161+
bodyReader, httpWriter := io.Pipe()
162+
163+
// gzipWriter compresses data to httpWriter.
164+
gzipWriter := gzip.NewWriter(httpWriter)
165+
166+
// errch collects any errors from the writing goroutine.
167+
errch := make(chan error, 1)
168+
169+
go func() {
170+
defer close(errch)
171+
sentErr := false
172+
sendErr := func(err error) {
173+
if !sentErr {
174+
errch <- err
175+
sentErr = true
176+
}
177+
}
178+
179+
// Copy our data to gzipWriter, which compresses it to
180+
// gzipWriter, which feeds it to bodyReader.
181+
if _, err := io.Copy(gzipWriter, dataReader); err != nil && err != io.ErrClosedPipe {
182+
sendErr(err)
183+
}
184+
if err := gzipWriter.Close(); err != nil && err != io.ErrClosedPipe {
185+
sendErr(err)
186+
}
187+
if err := httpWriter.Close(); err != nil && err != io.ErrClosedPipe {
188+
sendErr(err)
189+
}
190+
}()
191+
192+
// Send an HTTP request to the test server.
193+
req, err := http.NewRequest("PUT", ts.URL, bodyReader)
194+
if err != nil {
195+
log.Fatal(err)
196+
}
197+
198+
// Note that passing req to http.Client.Do promises that it
199+
// will close the body, in this case bodyReader.
200+
// That ensures that the goroutine will exit.
201+
resp, err := ts.Client().Do(req)
202+
if err != nil {
203+
log.Fatal(err)
204+
}
205+
206+
// Check whether there was an error compressing the data.
207+
if err := <-errch; err != nil {
208+
log.Fatal(err)
209+
}
210+
211+
// For this example we don't care about the response.
212+
resp.Body.Close()
213+
214+
// Output: the data to be compressed
215+
}

0 commit comments

Comments
 (0)