From 78384073b0376d04179e33be64ed4767422de343 Mon Sep 17 00:00:00 2001 From: Adhityaa Date: Mon, 11 Jun 2018 15:01:58 +0530 Subject: [PATCH] api: allow gzipped response --- api/config.go | 2 ++ api/errors.go | 1 + api/router_static.go | 31 +++++++++++++++++++++++++------ api/utils_gzip.go | 18 ++++++++++++++++++ 4 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 api/utils_gzip.go diff --git a/api/config.go b/api/config.go index ee61c73..b08d462 100644 --- a/api/config.go +++ b/api/config.go @@ -24,6 +24,8 @@ func parseConfig() error { "STATIC": binPath, + "GZIP_STATIC": "false", + "SMTP_USERNAME": "", "SMTP_PASSWORD": "", "SMTP_HOST": "", diff --git a/api/errors.go b/api/errors.go index 10fda74..2240a2d 100644 --- a/api/errors.go +++ b/api/errors.go @@ -37,3 +37,4 @@ var errorSessionAlreadyInUse = errors.New("Session is already in use.") var errorCannotReadResponse = errors.New("Cannot read response.") var errorNotModerator = errors.New("You need to be a moderator to do that.") var errorNotADirectory = errors.New("The given path is not a directory.") +var errorGzip = errors.New("Cannot GZip content.") diff --git a/api/router_static.go b/api/router_static.go index f23f63c..59038b7 100644 --- a/api/router_static.go +++ b/api/router_static.go @@ -25,7 +25,8 @@ type staticHtmlPlugs struct { } func initStaticRouter(router *mux.Router) error { - asset := make(map[string]string) + asset := make(map[string][]byte) + gzippedAsset := make(map[string][]byte) for _, dir := range []string{"js", "css", "images"} { sl := string(os.PathSeparator) @@ -52,12 +53,30 @@ func initStaticRouter(router *mux.Router) error { prefix += "window.commento_cdn='" + os.Getenv("CDN_PREFIX") + "';\n" } - asset[p] = prefix + string(contents) + gzip := (os.Getenv("GZIP_STATIC") == "true") - router.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", mime.TypeByExtension(path.Ext(r.URL.Path))) - fmt.Fprint(w, asset[r.URL.Path]) - }) + asset[p] = []byte(prefix + string(contents)) + if gzip { + gzippedAsset[p], err = gzipStatic(asset[p]) + if err != nil { + logger.Errorf("error gzipping %s: %v", p, err) + return err + } + } + + // faster than checking inside the handler + if !gzip { + router.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", mime.TypeByExtension(path.Ext(r.URL.Path))) + w.Write(asset[r.URL.Path]) + }) + } else { + router.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", mime.TypeByExtension(path.Ext(r.URL.Path))) + w.Header().Set("Content-Encoding", "gzip") + w.Write(gzippedAsset[r.URL.Path]) + }) + } } } diff --git a/api/utils_gzip.go b/api/utils_gzip.go new file mode 100644 index 0000000..c44a8af --- /dev/null +++ b/api/utils_gzip.go @@ -0,0 +1,18 @@ +package main + +import ( + "bytes" + "compress/gzip" +) + +func gzipStatic(b []byte) ([]byte, error) { + var buf bytes.Buffer + g := gzip.NewWriter(&buf) + if _, err := g.Write(b); err != nil { + g.Close() + return []byte{}, err + } + + g.Close() + return buf.Bytes(), nil +}