summaryrefslogtreecommitdiffhomepage
path: root/middleware/gzip
diff options
context:
space:
mode:
authorAbiola Ibrahim <[email protected]>2015-06-10 21:59:08 +0100
committerAbiola Ibrahim <[email protected]>2015-06-10 22:02:08 +0100
commite0f10c2b031618337557ea9a5aadabba4e44eb38 (patch)
treed35ccdb43e127078225fa298d56fd36e76d2bd65 /middleware/gzip
parent01aca02edc13abe52b5a8577fc79ba471b54f4a8 (diff)
downloadcaddy-e0f10c2b031618337557ea9a5aadabba4e44eb38.tar.gz
caddy-e0f10c2b031618337557ea9a5aadabba4e44eb38.zip
Gzip: Accept MIME types.
Diffstat (limited to 'middleware/gzip')
-rw-r--r--middleware/gzip/filter.go56
-rw-r--r--middleware/gzip/filter_test.go40
-rw-r--r--middleware/gzip/gzip_test.go54
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 {