From 2fa7c464f019f67c5c0494aaf5ac0f5ecc1ee7a7 Mon Sep 17 00:00:00 2001 From: Harrison Healey Date: Tue, 16 Jan 2018 12:03:31 -0500 Subject: Updated dependencies and added avct/uasurfer (#8089) * Updated dependencies and added avct/uasurfer * Added uasurfer to NOTICE.txt --- vendor/github.com/NYTimes/gziphandler/gzip.go | 35 +++++++++++----- vendor/github.com/NYTimes/gziphandler/gzip_test.go | 49 ++++++++++++++++++---- 2 files changed, 66 insertions(+), 18 deletions(-) (limited to 'vendor/github.com/NYTimes') diff --git a/vendor/github.com/NYTimes/gziphandler/gzip.go b/vendor/github.com/NYTimes/gziphandler/gzip.go index 13ee34a42..b3cb8315b 100644 --- a/vendor/github.com/NYTimes/gziphandler/gzip.go +++ b/vendor/github.com/NYTimes/gziphandler/gzip.go @@ -82,7 +82,14 @@ type GzipResponseWriter struct { buf []byte // Holds the first part of the write before reaching the minSize or the end of the write. contentTypes []string // Only compress if the response is one of these content-types. All are accepted if empty. - flushed bool // Indicate if the stream was already flushed +} + +type GzipResponseWriterWithCloseNotify struct { + *GzipResponseWriter +} + +func (w *GzipResponseWriterWithCloseNotify) CloseNotify() <-chan bool { + return w.ResponseWriter.(http.CloseNotifier).CloseNotify() } // Write appends data to the gzip writer. @@ -170,8 +177,7 @@ func (w *GzipResponseWriter) init() { func (w *GzipResponseWriter) Close() error { if w.gw == nil { // Gzip not trigged yet, write out regular response. - // WriteHeader only if it wasn't already wrote by a Flush - if !w.flushed && w.code != 0 { + if w.code != 0 { w.ResponseWriter.WriteHeader(w.code) } if w.buf != nil { @@ -194,16 +200,18 @@ func (w *GzipResponseWriter) Close() error { // http.ResponseWriter if it is an http.Flusher. This makes GzipResponseWriter // an http.Flusher. func (w *GzipResponseWriter) Flush() { - if w.gw != nil { - w.gw.Flush() + if w.gw == nil { + // Only flush once startGzip has been called. + // + // Flush is thus a no-op until the written body + // exceeds minSize. + return } + w.gw.Flush() + if fw, ok := w.ResponseWriter.(http.Flusher); ok { - if !w.flushed && w.code != 0 { - w.ResponseWriter.WriteHeader(w.code) - } fw.Flush() - w.flushed = true } } @@ -264,7 +272,6 @@ func GzipHandlerWithOpts(opts ...option) (func(http.Handler) http.Handler, error return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Add(vary, acceptEncoding) - if acceptsGzip(r) { gw := &GzipResponseWriter{ ResponseWriter: w, @@ -274,7 +281,13 @@ func GzipHandlerWithOpts(opts ...option) (func(http.Handler) http.Handler, error } defer gw.Close() - h.ServeHTTP(gw, r) + if _, ok := w.(http.CloseNotifier); ok { + gwcn := GzipResponseWriterWithCloseNotify{gw} + h.ServeHTTP(gwcn, r) + } else { + h.ServeHTTP(gw, r) + } + } else { h.ServeHTTP(w, r) } diff --git a/vendor/github.com/NYTimes/gziphandler/gzip_test.go b/vendor/github.com/NYTimes/gziphandler/gzip_test.go index 7decfd17b..ec1543372 100644 --- a/vendor/github.com/NYTimes/gziphandler/gzip_test.go +++ b/vendor/github.com/NYTimes/gziphandler/gzip_test.go @@ -306,23 +306,58 @@ func TestStatusCodes(t *testing.T) { } } -func TestStatusCodesFlushed(t *testing.T) { +func TestFlushBeforeWrite(t *testing.T) { + b := []byte(testBody) handler := GzipHandler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { rw.WriteHeader(http.StatusNotFound) rw.(http.Flusher).Flush() - rw.Write([]byte("Not found")) + rw.Write(b) })) r := httptest.NewRequest(http.MethodGet, "/", nil) - r.Header.Set(acceptEncoding, "gzip") + r.Header.Set("Accept-Encoding", "gzip") w := httptest.NewRecorder() handler.ServeHTTP(w, r) - result := w.Result() - if result.StatusCode != http.StatusNotFound { - t.Errorf("StatusCode should have been 404 but was %d", result.StatusCode) - } + res := w.Result() + assert.Equal(t, http.StatusNotFound, res.StatusCode) + assert.Equal(t, "gzip", res.Header.Get("Content-Encoding")) + assert.NotEqual(t, b, w.Body.Bytes()) } +func TestImplementCloseNotifier(t *testing.T) { + GzipHandler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request){ + _, ok := rw.(http.CloseNotifier) + assert.True(t, ok, "response writer must implement http.CloseNotifier") + })).ServeHTTP(&mockRWCloseNotify{}, &http.Request{}) +} + +func TestNotImplementCloseNotifier(t *testing.T) { + GzipHandler(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request){ + _, ok := rw.(http.CloseNotifier) + assert.False(t, ok, "response writer must not implement http.CloseNotifier") + })).ServeHTTP(httptest.NewRecorder(), &http.Request{}) +} + + +type mockRWCloseNotify struct{} + +func (m *mockRWCloseNotify) CloseNotify() <-chan bool { + panic("implement me") +} + +func (m *mockRWCloseNotify) Header() http.Header { + return http.Header{} +} + +func (m *mockRWCloseNotify) Write([]byte) (int, error) { + panic("implement me") +} + +func (m *mockRWCloseNotify) WriteHeader(int) { + panic("implement me") +} + + func TestIgnoreSubsequentWriteHeader(t *testing.T) { handler := GzipHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(500) -- cgit v1.2.3-1-g7c22