diff options
Diffstat (limited to 'vendor/github.com/tdewolff/minify/v2/minify.go')
-rw-r--r-- | vendor/github.com/tdewolff/minify/v2/minify.go | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/vendor/github.com/tdewolff/minify/v2/minify.go b/vendor/github.com/tdewolff/minify/v2/minify.go index 8e2e3fdb0..0e9a2e113 100644 --- a/vendor/github.com/tdewolff/minify/v2/minify.go +++ b/vendor/github.com/tdewolff/minify/v2/minify.go @@ -29,7 +29,7 @@ var Warning = log.New(os.Stderr, "WARNING: ", 0) var ErrNotExist = errors.New("minifier does not exist for mimetype") // ErrClosedWriter is returned when writing to a closed writer. -var ErrClosedWriter = errors.New("write on closed writer") +var ErrClosedWriter = errors.New("write on closed writer") // TODO: DEPRECATED, remove //////////////////////////////////////////////////////////////// @@ -253,32 +253,24 @@ func (m *M) Reader(mediatype string, r io.Reader) io.Reader { // writer makes sure that errors from the minifier are passed down through Close (can be blocking). type writer struct { - pw *io.PipeWriter + io.WriteCloser wg sync.WaitGroup - err error closed bool -} - -// Write intercepts any writes to the writer. -func (w *writer) Write(b []byte) (int, error) { - if w.closed { - return 0, ErrClosedWriter - } - n, err := w.pw.Write(b) - if w.err != nil { - err = w.err - } - return n, err + err error } // Close must be called when writing has finished. It returns the error from the minifier. -func (w *writer) Close() error { - if !w.closed { - w.pw.Close() - w.wg.Wait() - w.closed = true +func (z *writer) Close() error { + if z.closed { + return nil } - return w.err + z.closed = true + err := z.WriteCloser.Close() + z.wg.Wait() + if z.err == nil { + return err + } + return z.err } // Writer wraps a Writer interface and minifies the stream. @@ -286,17 +278,16 @@ func (w *writer) Close() error { // The writer must be closed explicitly. func (m *M) Writer(mediatype string, w io.Writer) io.WriteCloser { pr, pw := io.Pipe() - mw := &writer{pw, sync.WaitGroup{}, nil, false} - mw.wg.Add(1) + z := &writer{pw, sync.WaitGroup{}, false, nil} + z.wg.Add(1) go func() { - defer mw.wg.Done() - + defer z.wg.Done() + defer pr.Close() if err := m.Minify(mediatype, w, pr); err != nil { - mw.err = err + z.err = err } - pr.Close() }() - return mw + return z } // responseWriter wraps an http.ResponseWriter and makes sure that errors from the minifier are passed down through Close (can be blocking). @@ -305,7 +296,7 @@ func (m *M) Writer(mediatype string, w io.Writer) io.WriteCloser { type responseWriter struct { http.ResponseWriter - writer *writer + z io.Writer m *M mediatype string } @@ -319,20 +310,34 @@ func (w *responseWriter) WriteHeader(status int) { // Write intercepts any writes to the response writer. // The first write will extract the Content-Type as the mediatype. Otherwise it falls back to the RequestURI extension. func (w *responseWriter) Write(b []byte) (int, error) { - if w.writer == nil { + if w.z == nil { // first write if mediatype := w.ResponseWriter.Header().Get("Content-Type"); mediatype != "" { w.mediatype = mediatype } - w.writer = w.m.Writer(w.mediatype, w.ResponseWriter).(*writer) + if _, params, minifier := w.m.Match(w.mediatype); minifier != nil { + pr, pw := io.Pipe() + z := &writer{pw, sync.WaitGroup{}, false, nil} + z.wg.Add(1) + go func() { + defer z.wg.Done() + defer pr.Close() + if err := minifier(w.m, w.ResponseWriter, pr, params); err != nil { + z.err = err + } + }() + w.z = z + } else { + w.z = w.ResponseWriter + } } - return w.writer.Write(b) + return w.z.Write(b) } // Close must be called when writing has finished. It returns the error from the minifier. func (w *responseWriter) Close() error { - if w.writer != nil { - return w.writer.Close() + if closer, ok := w.z.(interface{ Close() error }); ok { + return closer.Close() } return nil } |