mirror of https://github.com/golang/go.git
216 lines
4.7 KiB
Go
216 lines
4.7 KiB
Go
// Copyright 2016 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package gzip_test
|
|
|
|
import (
|
|
"bytes"
|
|
"compress/gzip"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func Example_writerReader() {
|
|
var buf bytes.Buffer
|
|
zw := gzip.NewWriter(&buf)
|
|
|
|
// Setting the Header fields is optional.
|
|
zw.Name = "a-new-hope.txt"
|
|
zw.Comment = "an epic space opera by George Lucas"
|
|
zw.ModTime = time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC)
|
|
|
|
_, err := zw.Write([]byte("A long time ago in a galaxy far, far away..."))
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
if err := zw.Close(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
zr, err := gzip.NewReader(&buf)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC())
|
|
|
|
if _, err := io.Copy(os.Stdout, zr); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
if err := zr.Close(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Output:
|
|
// Name: a-new-hope.txt
|
|
// Comment: an epic space opera by George Lucas
|
|
// ModTime: 1977-05-25 00:00:00 +0000 UTC
|
|
//
|
|
// A long time ago in a galaxy far, far away...
|
|
}
|
|
|
|
func ExampleReader_Multistream() {
|
|
var buf bytes.Buffer
|
|
zw := gzip.NewWriter(&buf)
|
|
|
|
var files = []struct {
|
|
name string
|
|
comment string
|
|
modTime time.Time
|
|
data string
|
|
}{
|
|
{"file-1.txt", "file-header-1", time.Date(2006, time.February, 1, 3, 4, 5, 0, time.UTC), "Hello Gophers - 1"},
|
|
{"file-2.txt", "file-header-2", time.Date(2007, time.March, 2, 4, 5, 6, 1, time.UTC), "Hello Gophers - 2"},
|
|
}
|
|
|
|
for _, file := range files {
|
|
zw.Name = file.name
|
|
zw.Comment = file.comment
|
|
zw.ModTime = file.modTime
|
|
|
|
if _, err := zw.Write([]byte(file.data)); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
if err := zw.Close(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
zw.Reset(&buf)
|
|
}
|
|
|
|
zr, err := gzip.NewReader(&buf)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
for {
|
|
zr.Multistream(false)
|
|
fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC())
|
|
|
|
if _, err := io.Copy(os.Stdout, zr); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
fmt.Print("\n\n")
|
|
|
|
err = zr.Reset(&buf)
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
if err := zr.Close(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
// Output:
|
|
// Name: file-1.txt
|
|
// Comment: file-header-1
|
|
// ModTime: 2006-02-01 03:04:05 +0000 UTC
|
|
//
|
|
// Hello Gophers - 1
|
|
//
|
|
// Name: file-2.txt
|
|
// Comment: file-header-2
|
|
// ModTime: 2007-03-02 04:05:06 +0000 UTC
|
|
//
|
|
// 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
|
|
}
|