From 20fa672097edacc0a4935b3a1606fb12706b380a Mon Sep 17 00:00:00 2001 From: "Gerasimos (Makis) Maropoulos" Date: Sat, 26 Feb 2022 21:16:08 +0200 Subject: [PATCH] fix 2 minor issues --- HISTORY.md | 2 ++ .../basic/middleware/main.go | 17 +++++----- .../request-body/read-json-stream/main.go | 2 +- _examples/url-shortener/main.go | 7 ++-- _examples/url-shortener/main_test.go | 2 +- context/context.go | 34 +++++++++++++++++-- core/router/handler_execution_rules.go | 4 ++- 7 files changed, 49 insertions(+), 19 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index d8a529d6..fbdcdba6 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -28,6 +28,8 @@ The codebase for Dependency Injection, Internationalization and localization and ## Fixes and Improvements +- Fix a bug of `WithoutBodyConsumptionOnUnmarshal` configurator and a minor dependency injection issue caused by the previous alpha version between 20 and 26 February of 2022. + - New basic [cors middleware](middleware/cors). - New `httptest.NewServer` helper. - New [x/errors](x/errors) sub-package, helps with HTTP Wire Errors. Example can be found [here](_examples/routing/http-wire-errors/main.go). diff --git a/_examples/dependency-injection/basic/middleware/main.go b/_examples/dependency-injection/basic/middleware/main.go index 137b3d61..9c9d0e53 100644 --- a/_examples/dependency-injection/basic/middleware/main.go +++ b/_examples/dependency-injection/basic/middleware/main.go @@ -47,19 +47,20 @@ func newApp() *iris.Application { // or 202 status code and empty body // or a 409 status code and "my_error" body. app.ConfigureContainer(func(api *iris.APIContainer) { - // TODO: fix that test as well. - // api.Self.SetExecutionRules(iris.ExecutionRules{ - // Begin: iris.ExecutionOptions{ - // Force: true, - // }, - // }) + // Enable execution of middlewares without ctx.Next requirement. + api.Self.SetExecutionRules(iris.ExecutionRules{ + Begin: iris.ExecutionOptions{ + Force: true, + }, + }) api.Use(middleware) api.Post("/{id:int}", handler) }) app.Configure( - iris.WithOptimizations, /* optional */ - iris.WithoutBodyConsumptionOnUnmarshal /* required when more than one handler is consuming request payload(testInput) */) + iris.WithOptimizations, /* optional */ + iris.WithoutBodyConsumptionOnUnmarshal, /* required when more than one handler is consuming request payload(testInput) */ + ) return app } diff --git a/_examples/request-body/read-json-stream/main.go b/_examples/request-body/read-json-stream/main.go index dd9ac3a6..b5a18680 100644 --- a/_examples/request-body/read-json-stream/main.go +++ b/_examples/request-body/read-json-stream/main.go @@ -58,7 +58,7 @@ func postIndexStream(ctx iris.Context) { var users []User job := func(decode iris.DecodeFunc) error { var u User - if err := decode(&u); err != nil { + if err := decode(ctx, &u); err != nil { return err } users = append(users, u) diff --git a/_examples/url-shortener/main.go b/_examples/url-shortener/main.go index ff6bcb4b..8ce91c18 100644 --- a/_examples/url-shortener/main.go +++ b/_examples/url-shortener/main.go @@ -40,10 +40,7 @@ func newApp(db *DB) *iris.Application { // // Look ./templates/index.html#L16 tmpl.AddFunc("IsPositive", func(n int) bool { - if n > 0 { - return true - } - return false + return n > 0 }) app.RegisterView(tmpl) @@ -72,7 +69,7 @@ func newApp(db *DB) *iris.Application { return } - ctx.Redirect(value, iris.StatusTemporaryRedirect) + ctx.Redirect(value, iris.StatusBadGateway) } app.Get("/u/{shortkey}", func(ctx iris.Context) { execShortURL(ctx, ctx.Params().Get("shortkey")) diff --git a/_examples/url-shortener/main_test.go b/_examples/url-shortener/main_test.go index 75270e0f..46d1a90d 100644 --- a/_examples/url-shortener/main_test.go +++ b/_examples/url-shortener/main_test.go @@ -37,7 +37,7 @@ func TestURLShortener(t *testing.T) { // get e.GET("/u/" + keys[0]).Expect(). - Status(httptest.StatusTemporaryRedirect).Header("Location").Equal(originalURL) + Status(httptest.StatusBadGateway).Header("Location").Equal(originalURL) // save the same again, it should add a new key e.POST("/shorten"). diff --git a/context/context.go b/context/context.go index 7dafee56..045f4bf6 100644 --- a/context/context.go +++ b/context/context.go @@ -589,6 +589,11 @@ func (ctx *Context) HandlerIndex(n int) (currentIndex int) { //} // Alternative way is `!ctx.IsStopped()` if middleware make use of the `ctx.StopExecution()` on failure. func (ctx *Context) Proceed(h Handler) bool { + _, ok := ctx.ProceedAndReportIfStopped(h) + return ok +} + +func (ctx *Context) ProceedAndReportIfStopped(h Handler) (bool, bool) { ctx.proceeded = internalPauseExecutionIndex // Store the current index. @@ -604,15 +609,15 @@ func (ctx *Context) Proceed(h Handler) bool { // Stop called, return false but keep the handlers index. if afterIdx == stopExecutionIndex { - return false + return true, false } if proceededByNext { - return true + return false, true } // Next called or not. - return afterIdx > beforeIdx + return false, afterIdx > beforeIdx } // HandlerName returns the current handler's name, helpful for debugging. @@ -2382,6 +2387,20 @@ func wrapDecodeFunc(decodeFunc func(interface{}) error) DecodeFunc { } } +func (options JSONReader) unmarshal(ctx stdContext.Context, body []byte, outPtr interface{}) error { + if options.Optimize { + if outPtr != nil { + if _, supportsContext := outPtr.(unmarshalerContext); !supportsContext { + return gojson.Unmarshal(body, outPtr) + } + } + + return gojson.UnmarshalContext(ctx, body, outPtr) + } + + return json.Unmarshal(body, outPtr) +} + func (options JSONReader) getDecoder(r io.Reader, outPtr interface{}) (internalJSONDecoder, DecodeFunc) { var ( decoder internalJSONDecoder @@ -2429,6 +2448,15 @@ func (ctx *Context) ReadJSON(outPtr interface{}, opts ...JSONReader) error { options = opts[0] } + if ctx.IsRecordingBody() { + body, err := GetBody(ctx.request, true) + if err != nil { + return err + } + + return options.unmarshal(ctx.request.Context(), body, outPtr) + } + _, decodeFunc := options.getDecoder(ctx.request.Body, outPtr) return decodeFunc(ctx.request.Context(), outPtr) diff --git a/core/router/handler_execution_rules.go b/core/router/handler_execution_rules.go index 3ea0b069..fd94feb3 100644 --- a/core/router/handler_execution_rules.go +++ b/core/router/handler_execution_rules.go @@ -75,7 +75,9 @@ func (e ExecutionOptions) buildHandler(h context.Handler) context.Handler { return func(ctx *context.Context) { // Proceed will fire the handler and return false here if it doesn't contain a `ctx.Next()`, // so we add the `ctx.Next()` wherever is necessary in order to eliminate any dev's misuse. - if !ctx.Proceed(h) { + // + // 26 Feb 2022: check if manually stopped, and if it's then don't call ctx.Next. + if hasStopped, hasNext := ctx.ProceedAndReportIfStopped(h); !hasStopped && !hasNext { // `ctx.Next()` always checks for `ctx.IsStopped()` and handler(s) positions by-design. ctx.Next() }