-
-
Notifications
You must be signed in to change notification settings - Fork 15
/
responsefilters.go
87 lines (71 loc) · 2.95 KB
/
responsefilters.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package gzip
import (
"net/http"
"github.com/signalsciences/ac/acascii"
)
// ResponseHeaderFilter decide whether or not to compress response
// judging by response header
type ResponseHeaderFilter interface {
// ShouldCompress decide whether or not to compress response,
// judging by response header
ShouldCompress(header http.Header) bool
}
// interface guards
var (
_ ResponseHeaderFilter = (*SkipCompressedFilter)(nil)
_ ResponseHeaderFilter = (*ContentTypeFilter)(nil)
)
// SkipCompressedFilter judges whether content has been
// already compressed
type SkipCompressedFilter struct{}
// NewSkipCompressedFilter ...
func NewSkipCompressedFilter() *SkipCompressedFilter {
return &SkipCompressedFilter{}
}
// ShouldCompress implements ResponseHeaderFilter interface
//
// Content-Encoding: https://tools.ietf.org/html/rfc2616#section-3.5
func (s *SkipCompressedFilter) ShouldCompress(header http.Header) bool {
return header.Get("Content-Encoding") == "" && header.Get("Transfer-Encoding") == ""
}
// ContentTypeFilter judge via the response content type
//
// Omit this filter if you want to compress all content type.
type ContentTypeFilter struct {
Types *acascii.Matcher
AllowEmpty bool
}
// NewContentTypeFilter ...
func NewContentTypeFilter(types []string) *ContentTypeFilter {
var (
nonEmpty = make([]string, 0, len(types))
allowEmpty bool
)
for _, item := range types {
if item == "" {
allowEmpty = true
continue
}
nonEmpty = append(nonEmpty, item)
}
return &ContentTypeFilter{
Types: acascii.MustCompileString(nonEmpty),
AllowEmpty: allowEmpty,
}
}
// ShouldCompress implements RequestFilter interface
func (e *ContentTypeFilter) ShouldCompress(header http.Header) bool {
contentType := header.Get("Content-Type")
if contentType == "" {
return e.AllowEmpty
}
return e.Types.MatchString(contentType)
}
// defaultContentType is the list of default content types for which to enable gzip.
// original source:
// https://support.cloudflare.com/hc/en-us/articles/200168396-What-will-Cloudflare-compress-
var defaultContentType = []string{"text/html", "text/richtext", "text/plain", "text/css", "text/x-script", "text/x-component", "text/x-java-source", "text/x-markdown", "application/javascript", "application/x-javascript", "text/javascript", "text/js", "image/x-icon", "application/x-perl", "application/x-httpd-cgi", "text/xml", "application/xml", "application/xml+rss", "application/json", "multipart/bag", "multipart/mixed", "application/xhtml+xml", "font/ttf", "font/otf", "font/x-woff", "image/svg+xml", "application/vnd.ms-fontobject", "application/ttf", "application/x-ttf", "application/otf", "application/x-otf", "application/truetype", "application/opentype", "application/x-opentype", "application/font-woff", "application/eot", "application/font", "application/font-sfnt", "application/wasm"}
// DefaultContentTypeFilter permits
func DefaultContentTypeFilter() *ContentTypeFilter {
return NewContentTypeFilter(defaultContentType)
}