summaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/NYTimes/gziphandler/gzip.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/NYTimes/gziphandler/gzip.go')
-rw-r--r--Godeps/_workspace/src/github.com/NYTimes/gziphandler/gzip.go140
1 files changed, 0 insertions, 140 deletions
diff --git a/Godeps/_workspace/src/github.com/NYTimes/gziphandler/gzip.go b/Godeps/_workspace/src/github.com/NYTimes/gziphandler/gzip.go
deleted file mode 100644
index d0c85c6d3..000000000
--- a/Godeps/_workspace/src/github.com/NYTimes/gziphandler/gzip.go
+++ /dev/null
@@ -1,140 +0,0 @@
-package gziphandler
-
-import (
- "compress/gzip"
- "fmt"
- "net/http"
- "strconv"
- "strings"
- "sync"
-)
-
-const (
- vary = "Vary"
- acceptEncoding = "Accept-Encoding"
- contentEncoding = "Content-Encoding"
-)
-
-type codings map[string]float64
-
-// The default qvalue to assign to an encoding if no explicit qvalue is set.
-// This is actually kind of ambiguous in RFC 2616, so hopefully it's correct.
-// The examples seem to indicate that it is.
-const DEFAULT_QVALUE = 1.0
-
-var gzipWriterPool = sync.Pool{
- New: func() interface{} { return gzip.NewWriter(nil) },
-}
-
-// GzipResponseWriter provides an http.ResponseWriter interface, which gzips
-// bytes before writing them to the underlying response. This doesn't set the
-// Content-Encoding header, nor close the writers, so don't forget to do that.
-type GzipResponseWriter struct {
- gw *gzip.Writer
- http.ResponseWriter
-}
-
-// Write appends data to the gzip writer.
-func (w GzipResponseWriter) Write(b []byte) (int, error) {
- return w.gw.Write(b)
-}
-
-// Flush flushes the underlying *gzip.Writer and then the underlying
-// http.ResponseWriter if it is an http.Flusher. This makes GzipResponseWriter
-// an http.Flusher.
-func (w GzipResponseWriter) Flush() {
- w.gw.Flush()
- if fw, ok := w.ResponseWriter.(http.Flusher); ok {
- fw.Flush()
- }
-}
-
-// GzipHandler wraps an HTTP handler, to transparently gzip the response body if
-// the client supports it (via the Accept-Encoding header).
-func GzipHandler(h http.Handler) http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.Header().Add(vary, acceptEncoding)
-
- if acceptsGzip(r) {
- // Bytes written during ServeHTTP are redirected to this gzip writer
- // before being written to the underlying response.
- gzw := gzipWriterPool.Get().(*gzip.Writer)
- defer gzipWriterPool.Put(gzw)
- gzw.Reset(w)
- defer gzw.Close()
-
- w.Header().Set(contentEncoding, "gzip")
- h.ServeHTTP(GzipResponseWriter{gzw, w}, r)
- } else {
- h.ServeHTTP(w, r)
- }
- })
-}
-
-// acceptsGzip returns true if the given HTTP request indicates that it will
-// accept a gzippped response.
-func acceptsGzip(r *http.Request) bool {
- acceptedEncodings, _ := parseEncodings(r.Header.Get(acceptEncoding))
- return acceptedEncodings["gzip"] > 0.0
-}
-
-// parseEncodings attempts to parse a list of codings, per RFC 2616, as might
-// appear in an Accept-Encoding header. It returns a map of content-codings to
-// quality values, and an error containing the errors encounted. It's probably
-// safe to ignore those, because silently ignoring errors is how the internet
-// works.
-//
-// See: http://tools.ietf.org/html/rfc2616#section-14.3
-func parseEncodings(s string) (codings, error) {
- c := make(codings)
- e := make([]string, 0)
-
- for _, ss := range strings.Split(s, ",") {
- coding, qvalue, err := parseCoding(ss)
-
- if err != nil {
- e = append(e, err.Error())
-
- } else {
- c[coding] = qvalue
- }
- }
-
- // TODO (adammck): Use a proper multi-error struct, so the individual errors
- // can be extracted if anyone cares.
- if len(e) > 0 {
- return c, fmt.Errorf("errors while parsing encodings: %s", strings.Join(e, ", "))
- }
-
- return c, nil
-}
-
-// parseCoding parses a single conding (content-coding with an optional qvalue),
-// as might appear in an Accept-Encoding header. It attempts to forgive minor
-// formatting errors.
-func parseCoding(s string) (coding string, qvalue float64, err error) {
- for n, part := range strings.Split(s, ";") {
- part = strings.TrimSpace(part)
- qvalue = DEFAULT_QVALUE
-
- if n == 0 {
- coding = strings.ToLower(part)
-
- } else if strings.HasPrefix(part, "q=") {
- qvalue, err = strconv.ParseFloat(strings.TrimPrefix(part, "q="), 64)
-
- if qvalue < 0.0 {
- qvalue = 0.0
-
- } else if qvalue > 1.0 {
- qvalue = 1.0
- }
- }
- }
-
- if coding == "" {
- err = fmt.Errorf("empty content-coding")
- }
-
- return
-}