I am trying to create a very simple gzip middleware for static files. But I am calling next.ServeHTTP(w, r)
5 different places in the code, what happens if I defer this? Will this be called before the function that is returned is run?
This is what I have:
func gzipHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
// If for some weird reason client does not understand gzip, then continue.
next.ServeHTTP(w, r)
return
}
path := filepath.FromSlash(filepath.Join(cfg.PublicHTML, r.URL.Path))
if _, err := os.Stat(path); os.IsNotExist(err) {
// If file or folder does not exists, then continue.
next.ServeHTTP(w, r)
return
}
var ext string
for _, v := range cfg.GzipExt {
if strings.HasSuffix(r.URL.Path, v) {
ext = v
}
}
if ext == "" {
// This file should not be served as gzipped content.
next.ServeHTTP(w, r)
return
}
// Only serve gzipped file if it exists.
if _, err := os.Stat(path + ".gz"); os.IsNotExist(err) {
// TODO: Create the gzipped file.
// http://stackoverflow.com/questions/16890648/how-can-i-use-golangs-compress-gzip-package-to-gzip-a-file
next.ServeHTTP(w, r)
return
}
w.Header().Add("Content-Encoding", "gzip")
r.URL.Path = r.URL.Path + ".gz"
next.ServeHTTP(w, r)
})
}
Would it be possible here to defer next.ServeHTTP(w, r)? Like this:
func gzipHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer next.ServeHTTP(w, r)
if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
// If for some weird reason client does not understand gzip, then continue.
return
}
path := filepath.FromSlash(filepath.Join(cfg.PublicHTML, r.URL.Path))
if _, err := os.Stat(path); os.IsNotExist(err) {
// If file or folder does not exists, then continue.
return
}
var ext string
for _, v := range cfg.GzipExt {
if strings.HasSuffix(r.URL.Path, v) {
ext = v
}
}
if ext == "" {
// This file should not be served as gzipped content.
return
}
// Only serve gzipped file if it exists.
if _, err := os.Stat(path + ".gz"); os.IsNotExist(err) {
// TODO: Create the gzipped file.
// http://stackoverflow.com/questions/16890648/how-can-i-use-golangs-compress-gzip-package-to-gzip-a-file
return
}
w.Header().Add("Content-Encoding", "gzip")
r.URL.Path = r.URL.Path + ".gz"
})
}
I am using this in my main() function like this to serve static files:
router.NotFound = gzipHandler(fileServer())
If I defer next.ServeHTTP(w, r) like this, will it be executed before fileServer() is executed?