Ver código fonte

Added gzip flag

TC pushbot 5 4 anos atrás
pai
commit
06ed1bbea5
5 arquivos alterados com 101 adições e 5 exclusões
  1. 1 0
      main.flags.go
  2. 8 1
      main.go
  3. 3 2
      main.router.go
  4. 3 2
      mediaServer.go
  5. 86 0
      mod/network/gzipmiddleware/gzipmiddleware.go

+ 1 - 0
main.flags.go

@@ -51,6 +51,7 @@ var allow_upnp = flag.Bool("allow_upnp", false, "Enable uPNP service, recommende
 var allow_ssdp = flag.Bool("allow_ssdp", true, "Enable SSDP service, disable this if you do not want your device to be scanned by Windows's Network Neighborhood Page")
 var allow_mdns = flag.Bool("allow_mdns", true, "Enable MDNS service. Allow device to be scanned by nearby ArOZ Hosts")
 var disable_ip_resolve_services = flag.Bool("disable_ip_resolver", false, "Disable IP resolving if the system is running under reverse proxy environment")
+var enable_gzip = flag.Bool("gzip", false, "Enable gzip compress on file server")
 
 //Flags related to Security
 var use_tls = flag.Bool("tls", false, "Enable TLS on HTTP serving")

+ 8 - 1
main.go

@@ -12,6 +12,7 @@ import (
 	"syscall"
 
 	console "imuslab.com/arozos/mod/console"
+	"imuslab.com/arozos/mod/network/gzipmiddleware"
 )
 
 /*
@@ -111,7 +112,13 @@ func main() {
 
 	//Initiate all the static files transfer
 	fs := http.FileServer(http.Dir("./web"))
-	http.Handle("/", mroutner(fs))
+	if *enable_gzip {
+		//Gzip enabled. Always serve with gzip if header exists
+		http.Handle("/", gzipmiddleware.Compress(mroutner(fs)))
+	} else {
+		//Normal file server without gzip
+		http.Handle("/", mroutner(fs))
+	}
 
 	//Set database read write to ReadOnly after startup if demo mode
 	if *demo_mode {

+ 3 - 2
main.router.go

@@ -59,6 +59,7 @@ func mroutner(h http.Handler) http.Handler {
 				w.Header().Add("Content-Type", "application/javascript; charset=UTF-8")
 			}
 			h.ServeHTTP(w, r)
+
 		} else if len(r.URL.Path) >= len("/webdav") && r.URL.Path[:7] == "/webdav" {
 			WebDavHandler.HandleRequest(w, r)
 		} else if r.URL.Path == "/" && authAgent.CheckAuth(r) {
@@ -94,8 +95,8 @@ func mroutner(h http.Handler) http.Handler {
 			//User logged in. Continue to serve the file the client want
 			authAgent.UpdateSessionExpireTime(w, r)
 			if build_version == "development" {
-				//Disable caching when under development build
-				//w.Header().Set("Cache-Control", "no-cache, no-store, no-transform, must-revalidate, private, max-age=0")
+				//Do something if development build
+
 			}
 			if filepath.Ext("web"+fs.DecodeURI(r.RequestURI)) == ".js" {
 				//Fixed serve js meme type invalid bug on Firefox

+ 3 - 2
mediaServer.go

@@ -9,6 +9,7 @@ import (
 	"strings"
 
 	fs "imuslab.com/arozos/mod/filesystem"
+	"imuslab.com/arozos/mod/network/gzipmiddleware"
 )
 
 /*
@@ -29,8 +30,8 @@ PLEASE ALWAYS USE URLENCODE IN THE LINK PASSED INTO THE /media ENDPOINT
 //
 
 func mediaServer_init() {
-	http.HandleFunc("/media/", serverMedia)
-	http.HandleFunc("/media/getMime/", serveMediaMime)
+	http.HandleFunc("/media/", gzipmiddleware.CompressFunc(serverMedia))
+	http.HandleFunc("/media/getMime/", gzipmiddleware.CompressFunc(serveMediaMime))
 }
 
 //This function validate the incoming media request and return the real path for the targed file

+ 86 - 0
mod/network/gzipmiddleware/gzipmiddleware.go

@@ -0,0 +1,86 @@
+package gzipmiddleware
+
+import (
+	"compress/gzip"
+	"io"
+	"io/ioutil"
+	"net/http"
+	"strings"
+	"sync"
+)
+
+/*
+	This module handles web server related helpers and functions
+	author: tobychui
+
+*/
+
+var gzPool = sync.Pool{
+	New: func() interface{} {
+		w := gzip.NewWriter(ioutil.Discard)
+		gzip.NewWriterLevel(w, gzip.BestCompression)
+		return w
+	},
+}
+
+type gzipResponseWriter struct {
+	io.Writer
+	http.ResponseWriter
+}
+
+func (w *gzipResponseWriter) WriteHeader(status int) {
+	w.Header().Del("Content-Length")
+	w.ResponseWriter.WriteHeader(status)
+}
+
+func (w *gzipResponseWriter) Write(b []byte) (int, error) {
+	return w.Writer.Write(b)
+}
+
+/*
+	Compresstion function for http.FileServer
+*/
+func Compress(h http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
+			h.ServeHTTP(w, r)
+			return
+		}
+
+		w.Header().Set("Content-Encoding", "gzip")
+
+		gz := gzPool.Get().(*gzip.Writer)
+		defer gzPool.Put(gz)
+
+		gz.Reset(w)
+		defer gz.Close()
+
+		h.ServeHTTP(&gzipResponseWriter{ResponseWriter: w, Writer: gz}, r)
+	})
+}
+
+type gzipFuncResponseWriter struct {
+	io.Writer
+	http.ResponseWriter
+}
+
+func (w gzipFuncResponseWriter) Write(b []byte) (int, error) {
+	return w.Writer.Write(b)
+}
+
+/*
+	Compress Function for http.HandleFunc
+*/
+func CompressFunc(fn http.HandlerFunc) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
+			fn(w, r)
+			return
+		}
+		w.Header().Set("Content-Encoding", "gzip")
+		gz := gzip.NewWriter(w)
+		defer gz.Close()
+		gzr := gzipFuncResponseWriter{Writer: gz, ResponseWriter: w}
+		fn(gzr, r)
+	}
+}