mirror of
https://github.com/labstack/echo.git
synced 2024-11-24 08:22:21 +02:00
parent
eb84122d4e
commit
f7470482fe
18
bind.go
18
bind.go
@ -33,7 +33,7 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
|
||||
if req.ContentLength == 0 {
|
||||
if req.Method == GET || req.Method == DELETE {
|
||||
if err = b.bindData(i, c.QueryParams(), "query"); err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -44,28 +44,32 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
|
||||
case strings.HasPrefix(ctype, MIMEApplicationJSON):
|
||||
if err = json.NewDecoder(req.Body).Decode(i); err != nil {
|
||||
if ute, ok := err.(*json.UnmarshalTypeError); ok {
|
||||
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unmarshal type error: expected=%v, got=%v, field=%v, offset=%v", ute.Type, ute.Value, ute.Field, ute.Offset))
|
||||
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unmarshal type error: expected=%v, got=%v, field=%v, offset=%v", ute.Type, ute.Value, ute.Field, ute.Offset)).SetInternal(err)
|
||||
} else if se, ok := err.(*json.SyntaxError); ok {
|
||||
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: offset=%v, error=%v", se.Offset, se.Error()))
|
||||
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: offset=%v, error=%v", se.Offset, se.Error())).SetInternal(err)
|
||||
} else {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
case strings.HasPrefix(ctype, MIMEApplicationXML), strings.HasPrefix(ctype, MIMETextXML):
|
||||
if err = xml.NewDecoder(req.Body).Decode(i); err != nil {
|
||||
if ute, ok := err.(*xml.UnsupportedTypeError); ok {
|
||||
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unsupported type error: type=%v, error=%v", ute.Type, ute.Error()))
|
||||
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Unsupported type error: type=%v, error=%v", ute.Type, ute.Error())).SetInternal(err)
|
||||
} else if se, ok := err.(*xml.SyntaxError); ok {
|
||||
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: line=%v, error=%v", se.Line, se.Error()))
|
||||
return NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Syntax error: line=%v, error=%v", se.Line, se.Error())).SetInternal(err)
|
||||
} else {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
}
|
||||
case strings.HasPrefix(ctype, MIMEApplicationForm), strings.HasPrefix(ctype, MIMEMultipartForm):
|
||||
params, err := c.FormParams()
|
||||
if err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
if err = b.bindData(i, params, "form"); err != nil {
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error())
|
||||
return NewHTTPError(http.StatusBadRequest, err.Error()).SetInternal(err)
|
||||
}
|
||||
default:
|
||||
return ErrUnsupportedMediaType
|
||||
|
25
bind_test.go
25
bind_test.go
@ -2,11 +2,15 @@ package echo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@ -117,19 +121,24 @@ var values = map[string][]string{
|
||||
|
||||
func TestBindJSON(t *testing.T) {
|
||||
testBindOkay(t, strings.NewReader(userJSON), MIMEApplicationJSON)
|
||||
testBindError(t, strings.NewReader(invalidContent), MIMEApplicationJSON)
|
||||
testBindError(t, strings.NewReader(invalidContent), MIMEApplicationJSON, &json.SyntaxError{})
|
||||
testBindError(t, strings.NewReader(userJSONInvalidType), MIMEApplicationJSON, &json.UnmarshalTypeError{})
|
||||
}
|
||||
|
||||
func TestBindXML(t *testing.T) {
|
||||
testBindOkay(t, strings.NewReader(userXML), MIMEApplicationXML)
|
||||
testBindError(t, strings.NewReader(invalidContent), MIMEApplicationXML)
|
||||
testBindError(t, strings.NewReader(invalidContent), MIMEApplicationXML, errors.New(""))
|
||||
testBindError(t, strings.NewReader(userXMLConvertNumberError), MIMEApplicationXML, &strconv.NumError{})
|
||||
testBindError(t, strings.NewReader(userXMLUnsupportedTypeError), MIMEApplicationXML, &xml.SyntaxError{})
|
||||
testBindOkay(t, strings.NewReader(userXML), MIMETextXML)
|
||||
testBindError(t, strings.NewReader(invalidContent), MIMETextXML)
|
||||
testBindError(t, strings.NewReader(invalidContent), MIMETextXML, errors.New(""))
|
||||
testBindError(t, strings.NewReader(userXMLConvertNumberError), MIMETextXML, &strconv.NumError{})
|
||||
testBindError(t, strings.NewReader(userXMLUnsupportedTypeError), MIMETextXML, &xml.SyntaxError{})
|
||||
}
|
||||
|
||||
func TestBindForm(t *testing.T) {
|
||||
testBindOkay(t, strings.NewReader(userForm), MIMEApplicationForm)
|
||||
testBindError(t, nil, MIMEApplicationForm)
|
||||
testBindError(t, nil, MIMEApplicationForm, nil)
|
||||
e := New()
|
||||
req := httptest.NewRequest(POST, "/", strings.NewReader(userForm))
|
||||
rec := httptest.NewRecorder()
|
||||
@ -224,7 +233,7 @@ func TestBindMultipartForm(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBindUnsupportedMediaType(t *testing.T) {
|
||||
testBindError(t, strings.NewReader(invalidContent), MIMEApplicationJSON)
|
||||
testBindError(t, strings.NewReader(invalidContent), MIMEApplicationJSON, &json.SyntaxError{})
|
||||
}
|
||||
|
||||
func TestBindbindData(t *testing.T) {
|
||||
@ -246,7 +255,7 @@ func TestBindUnmarshalTypeError(t *testing.T) {
|
||||
|
||||
err := c.Bind(u)
|
||||
|
||||
he := &HTTPError{Code: http.StatusBadRequest, Message: "Unmarshal type error: expected=int, got=string, field=id, offset=14"}
|
||||
he := &HTTPError{Code: http.StatusBadRequest, Message: "Unmarshal type error: expected=int, got=string, field=id, offset=14", Internal: err.(*HTTPError).Internal}
|
||||
|
||||
assert.Equal(t, he, err)
|
||||
}
|
||||
@ -353,7 +362,7 @@ func testBindOkay(t *testing.T, r io.Reader, ctype string) {
|
||||
}
|
||||
}
|
||||
|
||||
func testBindError(t *testing.T, r io.Reader, ctype string) {
|
||||
func testBindError(t *testing.T, r io.Reader, ctype string, expectedInternal error) {
|
||||
e := New()
|
||||
req := httptest.NewRequest(POST, "/", r)
|
||||
rec := httptest.NewRecorder()
|
||||
@ -367,10 +376,12 @@ func testBindError(t *testing.T, r io.Reader, ctype string) {
|
||||
strings.HasPrefix(ctype, MIMEApplicationForm), strings.HasPrefix(ctype, MIMEMultipartForm):
|
||||
if assert.IsType(t, new(HTTPError), err) {
|
||||
assert.Equal(t, http.StatusBadRequest, err.(*HTTPError).Code)
|
||||
assert.IsType(t, expectedInternal, err.(*HTTPError).Internal)
|
||||
}
|
||||
default:
|
||||
if assert.IsType(t, new(HTTPError), err) {
|
||||
assert.Equal(t, ErrUnsupportedMediaType, err)
|
||||
assert.IsType(t, expectedInternal, err.(*HTTPError).Internal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
5
echo.go
5
echo.go
@ -702,6 +702,11 @@ func (he *HTTPError) Error() string {
|
||||
return fmt.Sprintf("code=%d, message=%v", he.Code, he.Message)
|
||||
}
|
||||
|
||||
func (he *HTTPError) SetInternal(err error) *HTTPError {
|
||||
he.Internal = err
|
||||
return he
|
||||
}
|
||||
|
||||
// WrapHandler wraps `http.Handler` into `echo.HandlerFunc`.
|
||||
func WrapHandler(h http.Handler) HandlerFunc {
|
||||
return func(c Context) error {
|
||||
|
11
echo_test.go
11
echo_test.go
@ -22,10 +22,13 @@ type (
|
||||
)
|
||||
|
||||
const (
|
||||
userJSON = `{"id":1,"name":"Jon Snow"}`
|
||||
userXML = `<user><id>1</id><name>Jon Snow</name></user>`
|
||||
userForm = `id=1&name=Jon Snow`
|
||||
invalidContent = "invalid content"
|
||||
userJSON = `{"id":1,"name":"Jon Snow"}`
|
||||
userXML = `<user><id>1</id><name>Jon Snow</name></user>`
|
||||
userForm = `id=1&name=Jon Snow`
|
||||
invalidContent = "invalid content"
|
||||
userJSONInvalidType = `{"id":"1","name":"Jon Snow"}`
|
||||
userXMLConvertNumberError = `<user><id>Number one</id><name>Jon Snow</name></user>`
|
||||
userXMLUnsupportedTypeError = `<user><>Number one</><name>Jon Snow</name></user>`
|
||||
)
|
||||
|
||||
const userJSONPretty = `{
|
||||
|
Loading…
Reference in New Issue
Block a user