@@ -10,7 +10,10 @@ import (
10
10
"fmt"
11
11
"io"
12
12
"log"
13
+ "net/http"
14
+ "net/http/httptest"
13
15
"os"
16
+ "strings"
14
17
"time"
15
18
)
16
19
@@ -126,3 +129,87 @@ func ExampleReader_Multistream() {
126
129
//
127
130
// Hello Gophers - 2
128
131
}
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