0

我的第一个想法是在过滤器中获取响应正文,然后使用像 tdewolff/minify 这样的缩小库并写入响应,但我找不到获取响应正文的方法。有没有更好的解决方案?

4

1 回答 1

0

通过查看文档,过滤器似乎可以访问Controller包含Response. 这个响应包含Out一个 ResponseWriter(因此也是一个 io.Writer)。我们只需要替换 Write 方法即可将写入重定向到压缩器,然后再写入响应写入器。为此,我们需要使用io.Pipe一个 goroutine。

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(它是 的一部分ResponseWriter),并围绕它包装一个结构。它保留了响应编写器的原始方法,但 Write 方法被覆盖以替换为PipeWriter. 这意味着对新响应编写器的任何写入都将转到PipeWriterPipeReader. 缩小从该读取器读取并写入原始响应写入器。

因为我们改变了 的值c.Response.Out,所以我们需要将它显式地传递给 goroutine。确保获得正确的 mimetype(通过扩展?)或直接调用适当的 minify 函数。

于 2015-10-11T23:02:48.747 回答