package gzip import ( "net/http" "path" "github.com/mholt/caddy/middleware" ) // Filter determines if a request should be gzipped. type Filter interface { // ShouldCompress tells if compression gzip compression // should be done on the request. ShouldCompress(*http.Request) bool } // ExtFilter is Filter for file name extensions. type ExtFilter struct { // Exts is the file name extensions to accept Exts Set } // textExts is a list of extensions for text related files. var textExts = []string{ ".html", ".htm", ".css", ".json", ".php", ".js", ".txt", ".md", ".xml", } // extWildCard is the wildcard for extensions. const extWildCard = "*" // DefaultExtFilter creates a default ExtFilter with // file extensions for text types. func DefaultExtFilter() ExtFilter { e := ExtFilter{make(Set)} for _, ext := range textExts { e.Exts.Add(ext) } return e } func (e ExtFilter) ShouldCompress(r *http.Request) bool { ext := path.Ext(r.URL.Path) return e.Exts.Contains(extWildCard) || e.Exts.Contains(ext) } // PathFilter is Filter for request path. type PathFilter struct { // IgnoredPaths is the paths to ignore IgnoredPaths Set } // ShouldCompress checks if the request path matches any of the // registered paths to ignore. If returns false if an ignored path // is found and true otherwise. func (p PathFilter) ShouldCompress(r *http.Request) bool { return !p.IgnoredPaths.ContainsFunc(func(value string) bool { return middleware.Path(r.URL.Path).Matches(value) }) } // Set stores distinct strings. type Set map[string]struct{} // Add adds an element to the set. func (s Set) Add(value string) { s[value] = struct{}{} } // Remove removes an element from the set. func (s Set) Remove(value string) { delete(s, value) } // Contains check if the set contains value. func (s Set) Contains(value string) bool { _, ok := s[value] return ok } // ContainsFunc is similar to Contains. It iterates all the // elements in the set and passes each to f. It returns true // on the first call to f that returns true and false otherwise. func (s Set) ContainsFunc(f func(string) bool) bool { for k, _ := range s { if f(k) { return true } } return false }