]> Cypherpunks.ru repositories - gostls13.git/commitdiff
compress/gzip: add example of compressing reader
authorIan Lance Taylor <iant@golang.org>
Wed, 2 Mar 2022 23:49:27 +0000 (15:49 -0800)
committerIan Lance Taylor <iant@golang.org>
Tue, 15 Mar 2022 17:59:01 +0000 (17:59 +0000)
For #51092

Change-Id: If0a233651ac75f113569ddfffd056084f6092564
Reviewed-on: https://go-review.googlesource.com/c/go/+/389514
Trust: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Joseph Tsai <joetsai@digital-static.net>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/compress/gzip/example_test.go

index ce29e9ba3656ed1e0b9eeaa3e6ddbd2373735672..27aae152d400a9431fbcf9ed5587741b5d424548 100644 (file)
@@ -10,7 +10,10 @@ import (
        "fmt"
        "io"
        "log"
+       "net/http"
+       "net/http/httptest"
        "os"
+       "strings"
        "time"
 )
 
@@ -126,3 +129,87 @@ func ExampleReader_Multistream() {
        //
        // Hello Gophers - 2
 }
+
+func Example_compressingReader() {
+       // This is an example of writing a compressing reader.
+       // This can be useful for an HTTP client body, as shown.
+
+       const testdata = "the data to be compressed"
+
+       // This HTTP handler is just for testing purposes.
+       handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
+               zr, err := gzip.NewReader(req.Body)
+               if err != nil {
+                       log.Fatal(err)
+               }
+
+               // Just output the data for the example.
+               if _, err := io.Copy(os.Stdout, zr); err != nil {
+                       log.Fatal(err)
+               }
+       })
+       ts := httptest.NewServer(handler)
+       defer ts.Close()
+
+       // The remainder is the example code.
+
+       // The data we want to compress, as an io.Reader
+       dataReader := strings.NewReader(testdata)
+
+       // bodyReader is the body of the HTTP request, as an io.Reader.
+       // httpWriter is the body of the HTTP request, as an io.Writer.
+       bodyReader, httpWriter := io.Pipe()
+
+       // gzipWriter compresses data to httpWriter.
+       gzipWriter := gzip.NewWriter(httpWriter)
+
+       // errch collects any errors from the writing goroutine.
+       errch := make(chan error, 1)
+
+       go func() {
+               defer close(errch)
+               sentErr := false
+               sendErr := func(err error) {
+                       if !sentErr {
+                               errch <- err
+                               sentErr = true
+                       }
+               }
+
+               // Copy our data to gzipWriter, which compresses it to
+               // gzipWriter, which feeds it to bodyReader.
+               if _, err := io.Copy(gzipWriter, dataReader); err != nil && err != io.ErrClosedPipe {
+                       sendErr(err)
+               }
+               if err := gzipWriter.Close(); err != nil && err != io.ErrClosedPipe {
+                       sendErr(err)
+               }
+               if err := httpWriter.Close(); err != nil && err != io.ErrClosedPipe {
+                       sendErr(err)
+               }
+       }()
+
+       // Send an HTTP request to the test server.
+       req, err := http.NewRequest("PUT", ts.URL, bodyReader)
+       if err != nil {
+               log.Fatal(err)
+       }
+
+       // Note that passing req to http.Client.Do promises that it
+       // will close the body, in this case bodyReader.
+       // That ensures that the goroutine will exit.
+       resp, err := ts.Client().Do(req)
+       if err != nil {
+               log.Fatal(err)
+       }
+
+       // Check whether there was an error compressing the data.
+       if err := <-errch; err != nil {
+               log.Fatal(err)
+       }
+
+       // For this example we don't care about the response.
+       resp.Body.Close()
+
+       // Output: the data to be compressed
+}