From 39e3911d4107ca741db9c23f514cf569f09f7168 Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Thu, 27 Aug 2020 07:23:56 +0300 Subject: [PATCH] fix future issues like #1607 --- context/compress.go | 24 +++++++++++++++++++ context/handler.go | 2 +- core/router/api_builder.go | 2 +- core/router/router_handlers_order_test.go | 29 ++++++++++++++--------- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/context/compress.go b/context/compress.go index d719116f..d8fc8cc3 100644 --- a/context/compress.go +++ b/context/compress.go @@ -184,6 +184,8 @@ type CompressResponseWriter struct { CompressWriter ResponseWriter + http.Hijacker + Disabled bool Encoding string Level int @@ -204,6 +206,21 @@ func AcquireCompressResponseWriter(w ResponseWriter, r *http.Request, level int) } v := compressWritersPool.Get().(*CompressResponseWriter) + + if h, ok := w.(http.Hijacker); ok { + v.Hijacker = h + } else { + v.Hijacker = nil + } + + // The Naive() should be used to check for Pusher, + // as examples explicitly says, so don't do it: + // if p, ok := w.Naive().(http.Pusher); ok { + // v.Pusher = p + // } else { + // v.Pusher = nil + // } + v.ResponseWriter = w v.Disabled = false if level == -1 && encoding == BROTLI { @@ -255,6 +272,13 @@ func (w *CompressResponseWriter) FlushResponse() { // write the status, after header set and before any flushed content sent. w.ResponseWriter.FlushResponse() + if w.IsHijacked() { + // net/http docs: + // It becomes the caller's responsibility to manage + // and close the connection. + return + } + w.CompressWriter.Close() // flushes and closes. } diff --git a/context/handler.go b/context/handler.go index f4d7056c..d8744ee6 100644 --- a/context/handler.go +++ b/context/handler.go @@ -259,7 +259,7 @@ func ingoreMainHandlerName(name string) bool { return false } -// Filter is just a type of func(Handler) bool which reports whether an action must be performed +// Filter is just a type of func(Context) bool which reports whether an action must be performed // based on the incoming request. // // See `NewConditionalHandler` for more. diff --git a/core/router/api_builder.go b/core/router/api_builder.go index a5dc863d..8cc58924 100644 --- a/core/router/api_builder.go +++ b/core/router/api_builder.go @@ -1354,7 +1354,7 @@ func getCaller() (string, int) { if relFile, err := filepath.Rel(wd, file); err == nil { if !strings.HasPrefix(relFile, "..") { // Only if it's relative to this path, not parent. - file = "./" + relFile + file = "./" + filepath.ToSlash(relFile) } } diff --git a/core/router/router_handlers_order_test.go b/core/router/router_handlers_order_test.go index 1ecfc67a..42083ae0 100644 --- a/core/router/router_handlers_order_test.go +++ b/core/router/router_handlers_order_test.go @@ -324,19 +324,26 @@ func TestUseWrapOrder(t *testing.T) { wrapRouter = func(w http.ResponseWriter, r *http.Request, router http.HandlerFunc) { if r.URL.Path == "/" { w.Write([]byte("#1 .WrapRouter\n")) - // Note for beginners, reading this test: - // if we write something here on a not found page, - // in the raw net/http wrapper like this one, - // then the response writer sends 200 status OK - // (on first write) and so any error handler will not be fired as expected, - // these are basic things. If you w.WriteHeader you cannot change the status code later on too. - // In Iris handlers, if you write before status code set, then it sends 200 - // and it cannot change too (if you want to change that behavior you use ctx.Record()). - // However if you - // just call ctx.StatusCode without content written then you are able to change the status code - // later on. + /* Note for new Gophers: + + If we write something here, on a not found resource, + in the raw `net/http` wrapper like this one, then the + response writer will send `200` status OK (on first write). + Any error handler will not be fired as expected. + Also, when `w.WriteHeader` is called you can NOT + change the status code later on. + + In Iris Handlers, if you write before status code set, + then it sends 200 status OK and it cannot change as well. + However if we just called `ctx.StatusCode` inside an + Iris Handler without any content written then we + would able to change the status code later on. + When you need to change that behavior you should + start the handler with a [ctx.Record()](responses/recorder.md) call. + */ } + // Continue by executing the Iris Router and leave it do its job. router(w, r) } )