From 742b802cf75981b6e94e61559db2a3f1630818bf Mon Sep 17 00:00:00 2001 From: Jason Kulatunga Date: Sat, 15 Jun 2024 07:56:55 +1000 Subject: [PATCH] adding http.CloseNotifier and http.Flusher interface to assetserver.contentTypeSniffer, for Gin (and other framework) compatibility. --- v3/internal/assetserver/assetserver.go | 2 +- .../assetserver/assetserver_webview.go | 2 +- .../assetserver/content_type_sniffer.go | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/v3/internal/assetserver/assetserver.go b/v3/internal/assetserver/assetserver.go index be862a3e2..6ff1b169f 100644 --- a/v3/internal/assetserver/assetserver.go +++ b/v3/internal/assetserver/assetserver.go @@ -59,7 +59,7 @@ func NewAssetServer(options *Options) (*AssetServer, error) { func (a *AssetServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) { start := time.Now() - wrapped := &contentTypeSniffer{rw: rw} + wrapped := newContentTypeSniffer(rw) defer func() { if _, err := wrapped.complete(); err != nil { a.options.Logger.Error("Error writing response data.", "uri", req.RequestURI, "error", err) diff --git a/v3/internal/assetserver/assetserver_webview.go b/v3/internal/assetserver/assetserver_webview.go index b569a4743..637642914 100644 --- a/v3/internal/assetserver/assetserver_webview.go +++ b/v3/internal/assetserver/assetserver_webview.go @@ -74,7 +74,7 @@ func (a *AssetServer) processWebViewRequestInternal(r webview.Request) { } }() - rw := &contentTypeSniffer{rw: wrw} // Make sure we have a Content-Type sniffer + var rw http.ResponseWriter = newContentTypeSniffer(wrw) // Make sure we have a Content-Type sniffer defer func() { if _, err := rw.complete(); err != nil { a.options.Logger.Error("Error writing response data.", "uri", uri, "error", err) diff --git a/v3/internal/assetserver/content_type_sniffer.go b/v3/internal/assetserver/content_type_sniffer.go index 44e4ceb39..e36db90e8 100644 --- a/v3/internal/assetserver/content_type_sniffer.go +++ b/v3/internal/assetserver/content_type_sniffer.go @@ -4,12 +4,20 @@ import ( "net/http" ) +func newContentTypeSniffer(rw http.ResponseWriter) *contentTypeSniffer { + return &contentTypeSniffer{ + rw: rw, + closeChannel: make(chan bool, 1), + } +} + type contentTypeSniffer struct { rw http.ResponseWriter prefix []byte status int headerCommitted bool headerWritten bool + closeChannel chan bool } // Unwrap returns the wrapped [http.ResponseWriter] for use with [http.ResponseController]. @@ -108,3 +116,19 @@ func (rw *contentTypeSniffer) complete() (n int, err error) { return } + +// CloseNotify implements the http.CloseNotifier interface. +func (rw *contentTypeSniffer) CloseNotify() <-chan bool { + return rw.closeChannel +} + +func (rw *contentTypeSniffer) closeClient() { + rw.closeChannel <- true +} + +// Flush implements the http.Flusher interface. +func (rw *contentTypeSniffer) Flush() { + if f, ok := rw.rw.(http.Flusher); ok { + f.Flush() + } +}