Merge 21fe9c2f2b635ec56da72746395b38e68caaa07f into 2285aa5430fb5e68bb55a89009fc4f5dd261b466

This commit is contained in:
heige 2022-12-22 08:02:05 +09:00 committed by GitHub
commit 734c73f388
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 38 additions and 29 deletions

View File

@ -86,7 +86,7 @@ var (
// Default returns the appropriate Binding instance based on the HTTP method
// and the content type.
func Default(method, contentType string) Binding {
if method == "GET" {
if method == http.MethodGet {
return Form
}

View File

@ -17,7 +17,8 @@ import (
)
var (
errUnknownType = errors.New("unknown type")
// ErrUnknownType unknown request type
ErrUnknownType = errors.New("unknown type")
// ErrConvertMapStringSlice can not convert to map[string][]string
ErrConvertMapStringSlice = errors.New("can not convert to map slices of strings")
@ -240,7 +241,7 @@ func setWithProperType(val string, value reflect.Value, field reflect.StructFiel
case reflect.Map:
return json.Unmarshal(bytesconv.StringToBytes(val), value.Addr().Interface())
default:
return errUnknownType
return ErrUnknownType
}
return nil
}

View File

@ -124,7 +124,7 @@ func TestMappingUnknownFieldType(t *testing.T) {
err := mappingByPtr(&s, formSource{"U": {"unknown"}}, "form")
assert.Error(t, err)
assert.Equal(t, errUnknownType, err)
assert.Equal(t, ErrUnknownType, err)
}
func TestMappingURI(t *testing.T) {

View File

@ -13,16 +13,21 @@ import (
"github.com/gin-gonic/gin/internal/json"
)
// EnableDecoderUseNumber is used to call the UseNumber method on the JSON
// Decoder instance. UseNumber causes the Decoder to unmarshal a number into an
// interface{} as a Number instead of as a float64.
var EnableDecoderUseNumber = false
var (
// EnableDecoderUseNumber is used to call the UseNumber method on the JSON
// Decoder instance. UseNumber causes the Decoder to unmarshal a number into an
// interface{} as a Number instead of as a float64.
EnableDecoderUseNumber = false
// EnableDecoderDisallowUnknownFields is used to call the DisallowUnknownFields method
// on the JSON Decoder instance. DisallowUnknownFields causes the Decoder to
// return an error when the destination is a struct and the input contains object
// keys which do not match any non-ignored, exported fields in the destination.
var EnableDecoderDisallowUnknownFields = false
// EnableDecoderDisallowUnknownFields is used to call the DisallowUnknownFields method
// on the JSON Decoder instance. DisallowUnknownFields causes the Decoder to
// return an error when the destination is a struct and the input contains object
// keys which do not match any non-ignored, exported fields in the destination.
EnableDecoderDisallowUnknownFields = false
// ErrInvalidRequest request is nil or request body is nil.
ErrInvalidRequest = errors.New("invalid request")
)
type jsonBinding struct{}
@ -32,8 +37,9 @@ func (jsonBinding) Name() string {
func (jsonBinding) Bind(req *http.Request, obj any) error {
if req == nil || req.Body == nil {
return errors.New("invalid request")
return ErrInvalidRequest
}
return decodeJSON(req.Body, obj)
}

View File

@ -822,11 +822,8 @@ func (c *Context) ContentType() string {
// IsWebsocket returns true if the request headers indicate that a websocket
// handshake is being initiated by the client.
func (c *Context) IsWebsocket() bool {
if strings.Contains(strings.ToLower(c.requestHeader("Connection")), "upgrade") &&
strings.EqualFold(c.requestHeader("Upgrade"), "websocket") {
return true
}
return false
return strings.Contains(strings.ToLower(c.requestHeader("Connection")), "upgrade") &&
strings.EqualFold(c.requestHeader("Upgrade"), "websocket")
}
func (c *Context) requestHeader(key string) string {

View File

@ -6,7 +6,6 @@ package gin
import (
"bytes"
"errors"
"fmt"
"io"
"log"
@ -47,6 +46,20 @@ func RecoveryWithWriter(out io.Writer, recovery ...RecoveryFunc) HandlerFunc {
return CustomRecoveryWithWriter(out, defaultHandleRecovery)
}
// IsBroken Check error for a broken connection
func IsBroken(err interface{}) bool {
if ne, ok := err.(*net.OpError); ok {
if se, ok := ne.Err.(*os.SyscallError); ok {
if errMsg := strings.ToLower(se.Error()); strings.Contains(errMsg, "broken pipe") ||
strings.Contains(errMsg, "connection reset by peer") {
return true
}
}
}
return false
}
// CustomRecoveryWithWriter returns a middleware for a given writer that recovers from any panics and calls the provided handle func to handle it.
func CustomRecoveryWithWriter(out io.Writer, handle RecoveryFunc) HandlerFunc {
var logger *log.Logger
@ -58,15 +71,7 @@ func CustomRecoveryWithWriter(out io.Writer, handle RecoveryFunc) HandlerFunc {
if err := recover(); err != nil {
// Check for a broken connection, as it is not really a
// condition that warrants a panic stack trace.
var brokenPipe bool
if ne, ok := err.(*net.OpError); ok {
var se *os.SyscallError
if errors.As(ne, &se) {
if strings.Contains(strings.ToLower(se.Error()), "broken pipe") || strings.Contains(strings.ToLower(se.Error()), "connection reset by peer") {
brokenPipe = true
}
}
}
var brokenPipe = IsBroken(err)
if logger != nil {
stack := stack(3)
httpRequest, _ := httputil.DumpRequest(c.Request, false)