From 32aa8d8852ce142f7fb90a58c4953ecf379b688b Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 31 May 2023 22:42:50 +0200 Subject: [PATCH] go: add+enable compression middleware --- app/routes.go | 25 ++++++++++++++++--------- app/routes_test.go | 16 +++++++++++----- go.mod | 3 +++ go.sum | 14 ++++++++++++++ handlers/middleware.go | 30 ++++++++++++++++++++++++++++++ run.go | 6 +++++- 6 files changed, 79 insertions(+), 15 deletions(-) diff --git a/app/routes.go b/app/routes.go index 1dfd1ba..740629b 100644 --- a/app/routes.go +++ b/app/routes.go @@ -12,7 +12,7 @@ import ( "github.com/labstack/echo/v4/middleware" ) -func (a *App) SetupRoutes() { +func (a *App) SetupRoutes() error { e := a.E() setting := a.setting assets := http.FileServer(a.getAssets()) @@ -25,6 +25,11 @@ func (a *App) SetupRoutes() { e.Renderer = modtmpl.Renderer + compress, err := handlers.WrapMiddlewareCompress() + if err != nil { + return err + } + // keep /static/* as a compatibility fallback for /assets. e.GET( "/static/*", @@ -37,28 +42,30 @@ func (a *App) SetupRoutes() { ) // alternative: // e.GET("/static/*", echo.WrapHandler(http.StripPrefix("/static/", assets))) - e.GET("/assets/*", echo.WrapHandler(http.StripPrefix("/assets/", assets)), handlers.MiddlewareCache) - e.HEAD("/assets/*", echo.WrapHandler(http.StripPrefix("/assets/", assets)), handlers.MiddlewareCache) + e.GET("/assets/*", echo.WrapHandler(http.StripPrefix("/assets/", assets)), handlers.MiddlewareCache, compress) + e.HEAD("/assets/*", echo.WrapHandler(http.StripPrefix("/assets/", assets)), handlers.MiddlewareCache, compress) e.GET("/healthz", handlers.Healthz()) e.GET("/health", handlers.Healthz()) - e.GET("/", handlers.Index()) - e.HEAD("/", handlers.Index()) - e.GET("/signin", handlers.Signin()) + e.GET("/", handlers.Index(), compress) + e.HEAD("/", handlers.Index(), compress) + e.GET("/signin", handlers.Signin(), compress) e.POST("/signin", handlers.SigninPost(a.db)) - e.GET("/signup", handlers.Signup()) + e.GET("/signup", handlers.Signup(), compress) e.POST("/signup", handlers.SignupPost(a.db)) - e.GET("/home", handlers.Home(a.db)) + e.GET("/home", handlers.Home(a.db), compress) e.GET("/manage/users", handlers.ManageUsers(), handlers.MiddlewareSession) e.GET("/manage/users/new", handlers.ManageUsers(), handlers.MiddlewareSession) e.GET("/manage/users/:id", handlers.ViewUser(), handlers.MiddlewareSession) e.POST("/manage/users/create", handlers.CreateUser(), handlers.MiddlewareSession) - e.GET("/logout", handlers.Logout()) + e.GET("/logout", handlers.Logout(), compress) e.POST("/logout", handlers.Logout()) // administrative endpoints. e.GET("/admin/*", handlers.Admin()) + + return nil } diff --git a/app/routes_test.go b/app/routes_test.go index af889d9..757fda0 100644 --- a/app/routes_test.go +++ b/app/routes_test.go @@ -69,7 +69,9 @@ func TestStaticRoute(t *testing.T) { t.Errorf("failed to initialise app: %v", a) } - a.SetupRoutes() + if err = a.SetupRoutes(); err != nil { + t.Errorf("failed to set up routes: %q", err) + } req := httptest.NewRequest(http.MethodGet, tstRoute, nil) rec := httptest.NewRecorder() @@ -95,7 +97,7 @@ func TestStaticRoute(t *testing.T) { } } -func BenchmarkStatic(b *testing.B) { +func BenchmarkStatic(b *testing.B) { //nolint:dupl setting := settings.New() a := &App{ templatesPath: "../templates", @@ -117,7 +119,9 @@ func BenchmarkStatic(b *testing.B) { b.Errorf("failed to initialise app: %v", a) } - a.SetupRoutes() + if err = a.SetupRoutes(); err != nil { + b.Errorf("failed to set up routes: %q", err) + } for i := 0; i < b.N; i++ { req := httptest.NewRequest(http.MethodGet, "/static/", nil) @@ -127,7 +131,7 @@ func BenchmarkStatic(b *testing.B) { } } -func BenchmarkStatic2(b *testing.B) { +func BenchmarkStatic2(b *testing.B) { //nolint:dupl setting := settings.New() a := &App{ templatesPath: "../templates", @@ -149,7 +153,9 @@ func BenchmarkStatic2(b *testing.B) { b.Errorf("failed to initialise app: %v", a) } - a.SetupRoutes() + if err = a.SetupRoutes(); err != nil { + b.Errorf("failed to set up routes: %q", err) + } for i := 0; i < b.N; i++ { req := httptest.NewRequest(http.MethodGet, "/static2/", nil) diff --git a/go.mod b/go.mod index 665061f..ae9a0d9 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.20 require ( entgo.io/ent v0.11.10 + github.com/CAFxX/httpcompression v0.0.8 github.com/google/uuid v1.3.0 github.com/gorilla/sessions v1.2.1 github.com/labstack/echo-contrib v0.14.1 @@ -22,6 +23,7 @@ require ( require ( ariga.io/atlas v0.9.2-0.20230303073438-03a4779a6338 // indirect github.com/agext/levenshtein v1.2.1 // indirect + github.com/andybalholm/brotli v1.0.4 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect @@ -34,6 +36,7 @@ require ( github.com/gorilla/securecookie v1.1.1 // indirect github.com/hashicorp/hcl/v2 v2.13.0 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect + github.com/klauspost/compress v1.14.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect diff --git a/go.sum b/go.sum index 3fb8312..b9bb3b2 100644 --- a/go.sum +++ b/go.sum @@ -3,9 +3,13 @@ ariga.io/atlas v0.9.2-0.20230303073438-03a4779a6338/go.mod h1:T230JFcENj4ZZzMkZr entgo.io/ent v0.11.10 h1:iqn32ybY5HRW3xSAyMNdNKpZhKgMf1Zunsej9yPKUI8= entgo.io/ent v0.11.10/go.mod h1:mzTZ0trE+jCQw/fnzijbm5Mck/l8Gbg7gC/+L1COyzM= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/CAFxX/httpcompression v0.0.8 h1:UBWojERnpCS6X7whJkGGZeCC3ruZBRwkwkcnfGfb0ko= +github.com/CAFxX/httpcompression v0.0.8/go.mod h1:bVd1taHK1vYb5SWe9lwNDCqrfj2ka+C1Zx7JHzxuHnU= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= +github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= @@ -28,6 +32,8 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/google/brotli/go/cbrotli v0.0.0-20210623081221-ce222e317e36 h1:qg5qEpjk1P1EMnInOCpxOpWSPRsspXJDT7P80y/JfFA= +github.com/google/brotli/go/cbrotli v0.0.0-20210623081221-ce222e317e36/go.mod h1:nOPhAkwVliJdNTkj3gXpljmWhjc4wCaVqbMJcPKWP4s= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -48,6 +54,9 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/klauspost/compress v1.14.1 h1:hLQYb23E8/fO+1u53d02A97a8UnsddcvYzq4ERRU4ds= +github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -83,6 +92,8 @@ github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/philandstuff/dhall-golang/v6 v6.0.2 h1:jv8fi4ZYiFe6uGrprx6dY7L3xPcgmEqWZo3s8ABCzkw= github.com/philandstuff/dhall-golang/v6 v6.0.2/go.mod h1:XRoxjsqZM2y7KPFhjV7CSVdWpV5CwuTzGjAY/v+1SUU= +github.com/pierrec/lz4/v4 v4.1.12 h1:44l88ehTZAUGW4VlO1QC4zkilL99M6Y9MXNwEs0uzP8= +github.com/pierrec/lz4/v4 v4.1.12/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -96,6 +107,7 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= @@ -104,6 +116,8 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/gozstd v1.11.0 h1:VV6qQFt+4sBBj9OJ7eKVvsFAMy59Urcs9Lgd+o5FOw0= +github.com/valyala/gozstd v1.11.0/go.mod h1:y5Ew47GLlP37EkTB+B4s7r6A5rdaeB7ftbl9zoYiIPQ= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= diff --git a/handlers/middleware.go b/handlers/middleware.go index d9bd01d..e830101 100644 --- a/handlers/middleware.go +++ b/handlers/middleware.go @@ -9,6 +9,9 @@ import ( "strings" moduser "git.dotya.ml/mirre-mt/pcmt/modules/user" + "github.com/CAFxX/httpcompression" + "github.com/CAFxX/httpcompression/contrib/andybalholm/brotli" + "github.com/CAFxX/httpcompression/contrib/compress/gzip" "github.com/labstack/echo-contrib/session" "github.com/labstack/echo/v4" ) @@ -119,3 +122,30 @@ func MiddlewareCache(next echo.HandlerFunc) echo.HandlerFunc { return next(c) } } + +func WrapMiddlewareCompress() (echo.MiddlewareFunc, error) { + brEnc, err := brotli.New(brotli.Options{}) + if err != nil { + return nil, err + } + + gzEnc, err := gzip.New(gzip.Options{}) + if err != nil { + return nil, err + } + + blocklist := true + a, _ := httpcompression.Adapter( + httpcompression.Compressor(brotli.Encoding, 1, brEnc), + httpcompression.Compressor(gzip.Encoding, 0, gzEnc), + httpcompression.Prefer(httpcompression.PreferServer), + httpcompression.MinSize(100), + httpcompression.ContentTypes([]string{ + "image/jpeg", + "image/gif", + "image/png", + }, blocklist), + ) + + return echo.WrapMiddleware(a), nil +} diff --git a/run.go b/run.go index 4d2886c..17640ef 100644 --- a/run.go +++ b/run.go @@ -163,7 +163,11 @@ func run() error { a.PrintConfiguration() a.SetEmbeds(templates, assets) - a.SetupRoutes() + + if err = a.SetupRoutes(); err != nil { + return err + } + a.SetEchoSettings() if err = setting.EraseENVs(); err != nil {