Minify html on-the-fly before sending it to users
This commit is contained in:
parent
b3039768af
commit
785130dc36
7 changed files with 66 additions and 6 deletions
5
go.mod
5
go.mod
|
|
@ -15,7 +15,9 @@ require (
|
||||||
github.com/gorilla/websocket v1.5.0
|
github.com/gorilla/websocket v1.5.0
|
||||||
github.com/julienschmidt/httprouter v1.3.0
|
github.com/julienschmidt/httprouter v1.3.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
|
github.com/pquerna/otp v1.4.0
|
||||||
github.com/rs/zerolog v1.28.0
|
github.com/rs/zerolog v1.28.0
|
||||||
|
github.com/tdewolff/minify v2.3.6+incompatible
|
||||||
github.com/tkw1536/goprogram v0.2.4
|
github.com/tkw1536/goprogram v0.2.4
|
||||||
golang.org/x/crypto v0.3.0
|
golang.org/x/crypto v0.3.0
|
||||||
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db
|
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db
|
||||||
|
|
@ -35,7 +37,8 @@ require (
|
||||||
github.com/jinzhu/now v1.1.5 // indirect
|
github.com/jinzhu/now v1.1.5 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||||
github.com/pquerna/otp v1.4.0 // indirect
|
github.com/tdewolff/parse v2.3.4+incompatible // indirect
|
||||||
|
github.com/tdewolff/test v1.0.7 // indirect
|
||||||
golang.org/x/sys v0.3.0 // indirect
|
golang.org/x/sys v0.3.0 // indirect
|
||||||
golang.org/x/tools v0.4.0 // indirect
|
golang.org/x/tools v0.4.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
9
go.sum
9
go.sum
|
|
@ -9,6 +9,7 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuW
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/feiin/sqlstring v0.3.0 h1:iyPEFijI2BxpY2M+AuhIvdNManzXa2OwGzuPaEMLUgo=
|
github.com/feiin/sqlstring v0.3.0 h1:iyPEFijI2BxpY2M+AuhIvdNManzXa2OwGzuPaEMLUgo=
|
||||||
github.com/feiin/sqlstring v0.3.0/go.mod h1:xpZTjVUw1nD3hMgF9SMRdPiooKSikLf4PS5j2NTn3RI=
|
github.com/feiin/sqlstring v0.3.0/go.mod h1:xpZTjVUw1nD3hMgF9SMRdPiooKSikLf4PS5j2NTn3RI=
|
||||||
|
|
@ -46,6 +47,7 @@ github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peK
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
|
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
|
||||||
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||||
|
|
@ -53,7 +55,14 @@ github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||||
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
|
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
|
||||||
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
|
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
|
github.com/tdewolff/minify v2.3.6+incompatible h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo=
|
||||||
|
github.com/tdewolff/minify v2.3.6+incompatible/go.mod h1:9Ov578KJUmAWpS6NeZwRZyT56Uf6o3Mcz9CEsg8USYs=
|
||||||
|
github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38=
|
||||||
|
github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ=
|
||||||
|
github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM=
|
||||||
|
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
|
||||||
github.com/tkw1536/goprogram v0.2.4 h1:1l3+j8xjY3E3uf+ba3QRGWm09ucFCKrnNLq6g1Gq8YA=
|
github.com/tkw1536/goprogram v0.2.4 h1:1l3+j8xjY3E3uf+ba3QRGWm09ucFCKrnNLq6g1Gq8YA=
|
||||||
github.com/tkw1536/goprogram v0.2.4/go.mod h1:3Ngcwy7jtsZ+pINc+JfLdf8TWbvthdSS2T6Vbg44Fy8=
|
github.com/tkw1536/goprogram v0.2.4/go.mod h1:3Ngcwy7jtsZ+pINc+JfLdf8TWbvthdSS2T6Vbg44Fy8=
|
||||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
"github.com/FAU-CDI/wisski-distillery/internal/dis/component"
|
||||||
|
"github.com/FAU-CDI/wisski-distillery/pkg/httpx"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UpdateInstanceList struct {
|
type UpdateInstanceList struct {
|
||||||
|
|
@ -77,6 +78,6 @@ func (ur *UpdateHome) Cron(ctx context.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ur.Dependencies.Home.homeBytes.Set(bytes)
|
ur.Dependencies.Home.homeBytes.Set(httpx.MinifyHTML(bytes))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,6 @@ var (
|
||||||
return json.Marshal(map[string]any{"status": text, "code": code})
|
return json.Marshal(map[string]any{"status": text, "code": code})
|
||||||
})
|
})
|
||||||
HTMLInterceptor = StatusInterceptor("text/html", func(code int, text string) ([]byte, error) {
|
HTMLInterceptor = StatusInterceptor("text/html", func(code int, text string) ([]byte, error) {
|
||||||
return []byte(`<!DOCTYPE HTML><title>` + text + `</title>` + text), nil
|
return MinifyHTML([]byte(`<!DOCTYPE HTML><title>` + text + `</title>` + text)), nil
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,15 @@ func WriteHTML[T any](result T, err error, template *template.Template, template
|
||||||
w.Header().Set("Content-Type", "text/html")
|
w.Header().Set("Content-Type", "text/html")
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
|
// minify html!
|
||||||
|
minifier := MinifyHTMLWriter(w)
|
||||||
|
defer minifier.Close()
|
||||||
|
|
||||||
|
// and return the template
|
||||||
if templateName != "" {
|
if templateName != "" {
|
||||||
template.ExecuteTemplate(w, templateName, result)
|
template.ExecuteTemplate(minifier, templateName, result)
|
||||||
} else {
|
} else {
|
||||||
template.Execute(w, result)
|
template.Execute(minifier, result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
42
pkg/httpx/html_minify.go
Normal file
42
pkg/httpx/html_minify.go
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
package httpx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/tdewolff/minify"
|
||||||
|
"github.com/tdewolff/minify/css"
|
||||||
|
"github.com/tdewolff/minify/html"
|
||||||
|
"github.com/tdewolff/minify/js"
|
||||||
|
"github.com/tdewolff/minify/svg"
|
||||||
|
)
|
||||||
|
|
||||||
|
// minifier holds the minfier used for all html minification
|
||||||
|
//
|
||||||
|
// NOTE(twiesing): We can't use an init function for this, because otherwise initialization order is incorrect.
|
||||||
|
var minifier = (func() *minify.M {
|
||||||
|
m := minify.New()
|
||||||
|
m.AddFunc("text/html", html.Minify)
|
||||||
|
m.AddFunc("text/css", css.Minify)
|
||||||
|
m.AddFunc("image/svg+xml", svg.Minify)
|
||||||
|
m.AddFuncRegexp(regexp.MustCompile("^(application|text)/(x-)?(java|ecma)script$"), js.Minify)
|
||||||
|
return m
|
||||||
|
})()
|
||||||
|
|
||||||
|
// MinifyHTMLWriter wraps the given io.Writer to minify the given html instead.
|
||||||
|
// The writer must be closed explicitly.
|
||||||
|
//
|
||||||
|
// Specific environments may chose to disable http minification, in which case MinifyHTMLWriter becomes the identity function.
|
||||||
|
func MinifyHTMLWriter(dest io.Writer) io.WriteCloser {
|
||||||
|
return minifier.Writer("text/html", dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MinifyHTML minifies the html source.
|
||||||
|
// If an error occurs, returns the unmodified source instead.
|
||||||
|
func MinifyHTML(source []byte) []byte {
|
||||||
|
result, err := minifier.Bytes("text/html", source)
|
||||||
|
if err != nil {
|
||||||
|
return source
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Lazy holds a lazily initialized value of T.
|
// Lazy holds a lazily initialized value of T.
|
||||||
// Lazy non-zero lazy must not be copied after first use.
|
// A non-zero lazy must not be copied after first use.
|
||||||
type Lazy[T any] struct {
|
type Lazy[T any] struct {
|
||||||
once sync.Once
|
once sync.Once
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue