diff options
author | Abiola Ibrahim <[email protected]> | 2015-06-10 21:59:08 +0100 |
---|---|---|
committer | Abiola Ibrahim <[email protected]> | 2015-06-10 22:02:08 +0100 |
commit | e0f10c2b031618337557ea9a5aadabba4e44eb38 (patch) | |
tree | d35ccdb43e127078225fa298d56fd36e76d2bd65 /middleware/gzip | |
parent | 01aca02edc13abe52b5a8577fc79ba471b54f4a8 (diff) | |
download | caddy-e0f10c2b031618337557ea9a5aadabba4e44eb38.tar.gz caddy-e0f10c2b031618337557ea9a5aadabba4e44eb38.zip |
Gzip: Accept MIME types.
Diffstat (limited to 'middleware/gzip')
-rw-r--r-- | middleware/gzip/filter.go | 56 | ||||
-rw-r--r-- | middleware/gzip/filter_test.go | 40 | ||||
-rw-r--r-- | middleware/gzip/gzip_test.go | 54 |
3 files changed, 122 insertions, 28 deletions
diff --git a/middleware/gzip/filter.go b/middleware/gzip/filter.go index 517f88587..a945fed90 100644 --- a/middleware/gzip/filter.go +++ b/middleware/gzip/filter.go @@ -3,13 +3,14 @@ package gzip import ( "net/http" "path" + "strings" "github.com/mholt/caddy/middleware" ) // Filter determines if a request should be gzipped. type Filter interface { - // ShouldCompress tells if compression gzip compression + // ShouldCompress tells if gzip compression // should be done on the request. ShouldCompress(*http.Request) bool } @@ -20,24 +21,12 @@ type ExtFilter struct { 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 -} - +// ShouldCompress checks if the request file extension matches any +// of the registered extensions. It returns true if the extension is +// found and false otherwise. func (e ExtFilter) ShouldCompress(r *http.Request) bool { ext := path.Ext(r.URL.Path) return e.Exts.Contains(extWildCard) || e.Exts.Contains(ext) @@ -50,7 +39,7 @@ type PathFilter struct { } // ShouldCompress checks if the request path matches any of the -// registered paths to ignore. If returns false if an ignored path +// registered paths to ignore. It 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 { @@ -58,6 +47,39 @@ func (p PathFilter) ShouldCompress(r *http.Request) bool { }) } +// MIMEFilter is Filter for request content types. +type MIMEFilter struct { + // Types is the MIME types to accept. + Types Set +} + +// defaultMIMETypes is the list of default MIME types to use. +var defaultMIMETypes = []string{ + "text/plain", "text/html", "text/css", "application/json", "application/javascript", + "text/x-markdown", "text/xml", "application/xml", +} + +// DefaultMIMEFilter creates a MIMEFilter with default types. +func DefaultMIMEFilter() MIMEFilter { + m := MIMEFilter{Types: make(Set)} + for _, mime := range defaultMIMETypes { + m.Types.Add(mime) + } + return m +} + +// ShouldCompress checks if the content type of the request +// matches any of the registered ones. It returns true if +// found and false otherwise. +func (m MIMEFilter) ShouldCompress(r *http.Request) bool { + return m.Types.Contains(r.Header.Get("Content-Type")) +} + +func ValidMIME(mime string) bool { + s := strings.Split(mime, "/") + return len(s) == 2 && strings.TrimSpace(s[0]) != "" && strings.TrimSpace(s[1]) != "" +} + // Set stores distinct strings. type Set map[string]struct{} diff --git a/middleware/gzip/filter_test.go b/middleware/gzip/filter_test.go index 56d054cfe..c3664cdd7 100644 --- a/middleware/gzip/filter_test.go +++ b/middleware/gzip/filter_test.go @@ -47,13 +47,13 @@ func TestSet(t *testing.T) { } func TestExtFilter(t *testing.T) { - var filter Filter = DefaultExtFilter() - _ = filter.(ExtFilter) - for i, e := range textExts { - r := urlRequest("file" + e) - if !filter.ShouldCompress(r) { - t.Errorf("Test %v: Should be valid filter", i) - } + var filter Filter = ExtFilter{make(Set)} + for _, e := range []string{".txt", ".html", ".css", ".md"} { + filter.(ExtFilter).Exts.Add(e) + } + r := urlRequest("file.txt") + if !filter.ShouldCompress(r) { + t.Errorf("Should be valid filter") } var exts = []string{ ".html", ".css", ".md", @@ -100,6 +100,32 @@ func TestPathFilter(t *testing.T) { } } +func TestMIMEFilter(t *testing.T) { + var filter Filter = DefaultMIMEFilter() + _ = filter.(MIMEFilter) + var mimes = []string{ + "text/html", "text/css", "application/json", + } + for i, m := range mimes { + r := urlRequest("file" + m) + r.Header.Set("Content-Type", m) + if !filter.ShouldCompress(r) { + t.Errorf("Test %v: Should be valid filter", i) + } + } + mimes = []string{ + "image/jpeg", "image/png", + } + filter = DefaultMIMEFilter() + for i, m := range mimes { + r := urlRequest("file" + m) + r.Header.Set("Content-Type", m) + if filter.ShouldCompress(r) { + t.Errorf("Test %v: Should not be valid filter", i) + } + } +} + func urlRequest(url string) *http.Request { r, _ := http.NewRequest("GET", url, nil) return r diff --git a/middleware/gzip/gzip_test.go b/middleware/gzip/gzip_test.go index 7015a5b77..ae0e300c8 100644 --- a/middleware/gzip/gzip_test.go +++ b/middleware/gzip/gzip_test.go @@ -16,13 +16,20 @@ func TestGzipHandler(t *testing.T) { for _, p := range badPaths { pathFilter.IgnoredPaths.Add(p) } + extFilter := ExtFilter{make(Set)} + for _, e := range []string{".txt", ".html", ".css", ".md"} { + extFilter.Exts.Add(e) + } gz := Gzip{Configs: []Config{ - Config{Filters: []Filter{DefaultExtFilter(), pathFilter}}, + Config{Filters: []Filter{pathFilter, extFilter}}, }} w := httptest.NewRecorder() gz.Next = nextFunc(true) - for _, e := range textExts { + var exts = []string{ + ".html", ".css", ".md", + } + for _, e := range exts { url := "/file" + e r, err := http.NewRequest("GET", url, nil) if err != nil { @@ -38,7 +45,7 @@ func TestGzipHandler(t *testing.T) { w = httptest.NewRecorder() gz.Next = nextFunc(false) for _, p := range badPaths { - for _, e := range textExts { + for _, e := range exts { url := p + "/file" + e r, err := http.NewRequest("GET", url, nil) if err != nil { @@ -54,7 +61,7 @@ func TestGzipHandler(t *testing.T) { w = httptest.NewRecorder() gz.Next = nextFunc(false) - exts := []string{ + exts = []string{ ".htm1", ".abc", ".mdx", } for _, e := range exts { @@ -70,6 +77,45 @@ func TestGzipHandler(t *testing.T) { } } + gz.Configs[0].Filters[1] = DefaultMIMEFilter() + w = httptest.NewRecorder() + gz.Next = nextFunc(true) + var mimes = []string{ + "text/html", "text/css", "application/json", + } + for _, m := range mimes { + url := "/file" + r, err := http.NewRequest("GET", url, nil) + if err != nil { + t.Error(err) + } + r.Header.Set("Content-Type", m) + r.Header.Set("Accept-Encoding", "gzip") + _, err = gz.ServeHTTP(w, r) + if err != nil { + t.Error(err) + } + } + + w = httptest.NewRecorder() + gz.Next = nextFunc(false) + mimes = []string{ + "image/jpeg", "image/png", + } + for _, m := range mimes { + url := "/file" + r, err := http.NewRequest("GET", url, nil) + if err != nil { + t.Error(err) + } + r.Header.Set("Content-Type", m) + r.Header.Set("Accept-Encoding", "gzip") + _, err = gz.ServeHTTP(w, r) + if err != nil { + t.Error(err) + } + } + } func nextFunc(shouldGzip bool) middleware.Handler { |