我的第一个想法是在过滤器中获取响应体,然后使用缩小库之一,如tdewolff / minify并写入响应,但我无法找到获得响应体的方法。 有没有更好的解决方案?
答案 0 :(得分:0)
通过查看文档,过滤器似乎可以访问包含Controller
的{{1}}类型。此响应包含Response
,它是ResponseWriter(因此也是io.Writer)。我们需要只替换Write方法将写入重定向到minifier,然后写入响应writer。我们需要使用Out
和goroutine。
io.Pipe
沿着这些方向的东西(未经测试)。这里我们接受传入的type MinifyResponseWriter struct {
http.ResponseWriter
io.Writer
}
func (f MinifyResponseWriter) Write(b []byte) (int, error) {
return f.Writer.Write(b)
}
func MinifyFilter(c *Controller, fc []Filter) {
pr, pw := io.Pipe()
go func(w io.Writer) {
m := minify.New()
m.AddFunc("text/css", css.Minify)
m.AddFunc("text/html", html.Minify)
m.AddFunc("text/javascript", js.Minify)
m.AddFunc("image/svg+xml", svg.Minify)
m.AddFuncRegexp(regexp.MustCompile("[/+]json$"), json.Minify)
m.AddFuncRegexp(regexp.MustCompile("[/+]xml$"), xml.Minify)
if err := m.Minify("mimetype", w, pr); err != nil {
panic(err)
}
}(c.Response.Out)
c.Response.Out = MinifyResponseWriter{c.Response.Out, pw}
}
(它是io.Writer
的一部分),并围绕它包装一个结构。它保留了响应编写器的原始方法,但Write方法被覆盖,被ResponseWriter
替换。这意味着对新响应编写器的任何写入都转到PipeWriter
,该PipeWriter
与PipeReader
耦合。缩小从该读取器读取并写入原始响应编写器。
因为我们更改了c.Response.Out
的值,所以我们需要将它明确地传递给goroutine。确保获得正确的mimetype(通过扩展名?)或直接调用适当的minify函数。