You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Please provide source code and commit sha if you found a bug.
Review existing issues and provide feedback or react to them.
Description
I am trying to minify the HTML/JS/CSS output before finally being gzipped using GIN's internal compression process. I have verified my middleware is working and outputting correctly for the minifying process. When I enable compression (which is the step after minifying), it completes the response with the proper coding type, but the body of the request is empty. If I turn it off, I once again see my minified output. Any help understanding what I am doing wrong or if this is a bug is appreciated.
How to reproduce
package middleware
import (
"bytes"
"log"
"regexp"
"github.com/gin-gonic/gin"
"github.com/tdewolff/minify/v2"
"github.com/tdewolff/minify/v2/css"
"github.com/tdewolff/minify/v2/html"
"github.com/tdewolff/minify/v2/js"
"github.com/tdewolff/minify/v2/json"
"github.com/tdewolff/minify/v2/svg"
"github.com/tdewolff/minify/v2/xml"
)
func MinifyHTML() gin.HandlerFunc {
return func(c *gin.Context) {
log.Println("MinifyHTML middleware invoked")
// Intercept the response with a buffer
var buffer bytes.Buffer
writer := &captureWriter{
ResponseWriter: c.Writer,
Buffer: &buffer,
}
c.Writer = writer
// Process the request
c.Next()
// Check if the response is HTML
contentType := c.Writer.Header().Get("Content-Type")
log.Printf("MinifyHTML: Content-Type: %s", contentType)
if contentType != "text/html; charset=utf-8" {
log.Println("MinifyHTML: Skipping non-HTML response")
writer.FlushBufferToResponse() // Write original response to the client
return
}
// Minify the HTML
log.Println("MinifyHTML: Minifying HTML response")
m := minify.New()
m.AddFunc("text/css", css.Minify)
m.AddFunc("text/html", html.Minify)
m.AddFunc("image/svg+xml", svg.Minify)
m.AddFuncRegexp(regexp.MustCompile("^(application|text)/(x-)?(java|ecma)script$"), js.Minify)
m.AddFuncRegexp(regexp.MustCompile("[/+]json$"), json.Minify)
m.AddFuncRegexp(regexp.MustCompile("[/+]xml$"), xml.Minify)
minified, err := m.String("text/html", buffer.String())
if err != nil {
log.Printf("MinifyHTML: Minification failed: %v", err)
writer.FlushBufferToResponse() // Write original response to the client
return
}
// Replace the buffered content with the minified content
log.Printf("MinifyHTML: Writing minified content of size: %d bytes", len(minified))
writer.ReplaceBuffer([]byte(minified))
}
}
// captureWriter intercepts and buffers the response
type captureWriter struct {
gin.ResponseWriter
Buffer *bytes.Buffer
}
func (w *captureWriter) Write(data []byte) (int, error) {
return w.Buffer.Write(data)
}
func (w *captureWriter) FlushBufferToResponse() {
if w.Buffer.Len() > 0 {
_, err := w.ResponseWriter.Write(w.Buffer.Bytes())
if err != nil {
log.Printf("captureWriter: Failed to flush buffer: %v", err)
}
}
}
func (w *captureWriter) ReplaceBuffer(data []byte) {
w.Buffer.Reset()
w.Buffer.Write(data)
_, err := w.ResponseWriter.Write(w.Buffer.Bytes())
if err != nil {
log.Printf("captureWriter: Failed to write replaced buffer: %v", err)
}
}
//Middleware setup:
r.Use(middleware.MinifyHTML())
r.Use(gzip.Gzip(gzip.DefaultCompression))
Hello @rniedosmialek, I think the problem arises from a confusing middleware ordering. As the gzip compression and the minifying middleware process the outgoing response, meaning it works after the controller logic runs, the ordering is switched: The last middleware you register is the first to get called after the controller logic.
So, switching the order solved it for me (using your reproduction example):
Description
I am trying to minify the HTML/JS/CSS output before finally being gzipped using GIN's internal compression process. I have verified my middleware is working and outputting correctly for the minifying process. When I enable compression (which is the step after minifying), it completes the response with the proper coding type, but the body of the request is empty. If I turn it off, I once again see my minified output. Any help understanding what I am doing wrong or if this is a bug is appreciated.
How to reproduce
Expectations
Actual result
Environment
The text was updated successfully, but these errors were encountered: