2017-07-13 15:56:01 +00:00
|
|
|
package gziphandler
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
|
|
|
"net"
|
|
|
|
"net/http"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
contentEncodingHeader = "Content-Encoding"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ----------
|
|
|
|
|
|
|
|
// http.ResponseWriter
|
|
|
|
// http.Hijacker
|
|
|
|
type GzipWriter interface {
|
|
|
|
Header() http.Header
|
|
|
|
Write([]byte) (int, error)
|
|
|
|
WriteHeader(int)
|
|
|
|
Hijack() (net.Conn, *bufio.ReadWriter, error)
|
|
|
|
Close() error
|
|
|
|
SetResponseWriter(http.ResponseWriter)
|
|
|
|
setIndex(int)
|
|
|
|
setMinSize(int)
|
2017-08-21 09:10:03 +00:00
|
|
|
setContentTypes([]string)
|
2017-07-13 15:56:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (w *GzipResponseWriter) SetResponseWriter(rw http.ResponseWriter) {
|
|
|
|
w.ResponseWriter = rw
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *GzipResponseWriter) setIndex(index int) {
|
|
|
|
w.index = index
|
|
|
|
}
|
|
|
|
|
|
|
|
func (w *GzipResponseWriter) setMinSize(minSize int) {
|
|
|
|
w.minSize = minSize
|
|
|
|
}
|
|
|
|
|
2017-08-21 09:10:03 +00:00
|
|
|
func (w *GzipResponseWriter) setContentTypes(contentTypes []string) {
|
|
|
|
w.contentTypes = contentTypes
|
|
|
|
}
|
|
|
|
|
2017-07-13 15:56:01 +00:00
|
|
|
// --------
|
|
|
|
|
|
|
|
type GzipResponseWriterWrapper struct {
|
|
|
|
GzipResponseWriter
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *GzipResponseWriterWrapper) Write(b []byte) (int, error) {
|
|
|
|
if g.gw == nil && isEncoded(g.Header()) {
|
2017-08-21 09:10:03 +00:00
|
|
|
if g.code != 0 {
|
|
|
|
g.ResponseWriter.WriteHeader(g.code)
|
|
|
|
}
|
2017-07-13 15:56:01 +00:00
|
|
|
return g.ResponseWriter.Write(b)
|
|
|
|
}
|
|
|
|
return g.GzipResponseWriter.Write(b)
|
|
|
|
}
|
|
|
|
|
|
|
|
func isEncoded(headers http.Header) bool {
|
|
|
|
header := headers.Get(contentEncodingHeader)
|
|
|
|
// According to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding,
|
|
|
|
// content is not encoded if the header 'Content-Encoding' is empty or equals to 'identity'.
|
|
|
|
return header != "" && header != "identity"
|
|
|
|
}
|