Skip to content

Instantly share code, notes, and snippets.

@bradclawsie
Forked from schmichael/gist:7379338
Last active November 17, 2015 21:34
Show Gist options
  • Save bradclawsie/5a2cc1c52824679c41e8 to your computer and use it in GitHub Desktop.
Save bradclawsie/5a2cc1c52824679c41e8 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"compress/gzip"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
)
func gzipHandler(rw http.ResponseWriter, r *http.Request) {
log.Printf("Recv'd request")
defer r.Body.Close()
gr, err := gzip.NewReader(r.Body)
if err != nil {
log.Fatal(err)
}
defer gr.Close()
plaintext, err := ioutil.ReadAll(gr)
if err != nil {
log.Fatal(err)
} else {
log.Printf("Sample: %s", string(plaintext[0:100]))
}
rw.Write([]byte(fmt.Sprintf("Recv'd %d plaintext bytes", len(plaintext))))
}
func main() {
http.HandleFunc("/foo", gzipHandler)
go http.ListenAndServe(":8080", nil)
in, err := os.Open("/usr/share/dict/words")
if err != nil {
log.Fatal(err)
}
// gzip writes to pipe, http reads from pipe
pr, pw := io.Pipe()
// buffer readers from file, writes to pipe
bufin := bufio.NewReader(in)
// gzip wraps buffer writer
gw := gzip.NewWriter(pw)
// Actually start reading from the file and writing to gzip
go func() {
log.Printf("Start writing")
n, err := bufin.WriteTo(gw)
if err != nil {
log.Fatal(err)
}
gw.Close()
pw.Close()
log.Printf("Done writing: %d", n)
}()
req, err := http.NewRequest("POST", "http://localhost:8080/foo", pr)
if err != nil {
log.Fatal(err)
}
log.Printf("Making request")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
log.Printf("Done! Received: \n%s", string(respBody))
}
@bradclawsie
Copy link
Author

explanation:

  • line 61 initiates req to webserver, where POSTed data will be read from pr, the read end of the io.Pipe
  • pr is a pipe connected to pw, set to read what is written to pw
  • line 50: goroutine starts reading from dict plain text file and will write to gw, the gzip writer connected to pw (producing a gzip bytestream to pr to POST to /foo)
  • on line 61, when the req is made, /foo will handle the req and call a readAll on its r reader arg, which is pr
  • this triggers pw to write the contents of gw to pr
  • in a sense this is a streaming interface

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment