remove default return handler from macaron (#38887)

This commit is contained in:
Serge Zaitsev 2021-09-09 16:41:34 +03:00 committed by GitHub
parent 792fa63725
commit 4c921cf120
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 3 additions and 92 deletions

View File

@ -64,27 +64,13 @@ func (ctx *Context) Next() {
ctx.run()
}
// Written returns whether the context response has been written to
func (ctx *Context) Written() bool {
return ctx.Resp.Written()
}
func (ctx *Context) run() {
for ctx.index <= len(ctx.handlers) {
vals, err := ctx.Invoke(ctx.handler())
if err != nil {
if _, err := ctx.Invoke(ctx.handler()); err != nil {
panic(err)
}
ctx.index++
// if the handler returned something, write it to the http response
if len(vals) > 0 {
ev := ctx.GetVal(reflect.TypeOf(ReturnHandler(nil)))
handleReturn := ev.Interface().(ReturnHandler)
handleReturn(ctx, vals)
}
if ctx.Written() {
if ctx.Resp.Written() {
return
}
}

View File

@ -160,7 +160,6 @@ func (m *Macaron) createContext(rw http.ResponseWriter, req *http.Request) *Cont
Data: make(map[string]interface{}),
}
req = req.WithContext(context.WithValue(req.Context(), macaronContextKey{}, c))
c.Map(defaultReturnHandler())
c.Map(c)
c.MapTo(c.Resp, (*http.ResponseWriter)(nil))
c.Map(req)

View File

@ -1,74 +0,0 @@
// Copyright 2013 Martini Authors
// Copyright 2014 The Macaron Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.
package macaron
import (
"net/http"
"reflect"
)
// ReturnHandler is a service that Martini provides that is called
// when a route handler returns something. The ReturnHandler is
// responsible for writing to the ResponseWriter based on the values
// that are passed into this function.
type ReturnHandler func(*Context, []reflect.Value)
func canDeref(val reflect.Value) bool {
return val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr
}
func isError(val reflect.Value) bool {
_, ok := val.Interface().(error)
return ok
}
func isByteSlice(val reflect.Value) bool {
return val.Kind() == reflect.Slice && val.Type().Elem().Kind() == reflect.Uint8
}
func defaultReturnHandler() ReturnHandler {
return func(ctx *Context, vals []reflect.Value) {
rv := ctx.GetVal(InterfaceOf((*http.ResponseWriter)(nil)))
resp := rv.Interface().(http.ResponseWriter)
var respVal reflect.Value
if len(vals) > 1 && vals[0].Kind() == reflect.Int {
resp.WriteHeader(int(vals[0].Int()))
respVal = vals[1]
} else if len(vals) > 0 {
respVal = vals[0]
if isError(respVal) {
err := respVal.Interface().(error)
if err != nil {
http.Error(resp, err.Error(), 500)
}
return
} else if canDeref(respVal) {
if respVal.IsNil() {
return // Ignore nil error
}
}
}
if canDeref(respVal) {
respVal = respVal.Elem()
}
if isByteSlice(respVal) {
_, _ = resp.Write(respVal.Bytes())
} else {
_, _ = resp.Write([]byte(respVal.String()))
}
}
}

View File

@ -128,7 +128,7 @@ func Recovery(cfg *setting.Cfg) macaron.Handler {
panicLogger.Error("Request error", "error", r, "stack", string(stack))
// if response has already been written, skip.
if c.Written() {
if c.Resp.Written() {
return
}