Skip to content

Instantly share code, notes, and snippets.

@schmichael
Created November 8, 2013 23:32
Show Gist options
  • Star 27 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save schmichael/7379338 to your computer and use it in GitHub Desktop.
Save schmichael/7379338 to your computer and use it in GitHub Desktop.
Transparently compress and upload a file in golang
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 and wr
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))
}
@jyidiego
Copy link

Thanks for this. Certainly helpful for a newbie like me. :-)

@ivan2kh
Copy link

ivan2kh commented Feb 8, 2015

            pr, pw := io.Pipe()
            gw := gzip.NewWriter(pw)
            go func() {
                n, err := io.Copy(gw, in)
                gw.Close()
                pw.Close()
                log.Printf("copied    %v %v", n, err)
            }()

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