@ -84,6 +84,7 @@ var (
|
||||
YAML BindingBody = yamlBinding{}
|
||||
Uri BindingUri = uriBinding{}
|
||||
Header Binding = headerBinding{}
|
||||
Plain BindingBody = plainBinding{}
|
||||
TOML BindingBody = tomlBinding{}
|
||||
)
|
||||
|
||||
|
@ -81,6 +81,7 @@ var (
|
||||
Uri = uriBinding{}
|
||||
Header = headerBinding{}
|
||||
TOML = tomlBinding{}
|
||||
Plain = plainBinding{}
|
||||
)
|
||||
|
||||
// Default returns the appropriate Binding instance based on the HTTP method
|
||||
|
@ -1342,6 +1342,46 @@ func (h hook) Read([]byte) (int, error) {
|
||||
return 0, errors.New("error")
|
||||
}
|
||||
|
||||
type failRead struct{}
|
||||
|
||||
func (f *failRead) Read(b []byte) (n int, err error) {
|
||||
return 0, errors.New("my fail")
|
||||
}
|
||||
|
||||
func (f *failRead) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestPlainBinding(t *testing.T) {
|
||||
p := Plain
|
||||
assert.Equal(t, "plain", p.Name())
|
||||
|
||||
var s string
|
||||
req := requestWithBody("POST", "/", "test string")
|
||||
assert.NoError(t, p.Bind(req, &s))
|
||||
assert.Equal(t, s, "test string")
|
||||
|
||||
var bs []byte
|
||||
req = requestWithBody("POST", "/", "test []byte")
|
||||
assert.NoError(t, p.Bind(req, &bs))
|
||||
assert.Equal(t, bs, []byte("test []byte"))
|
||||
|
||||
var i int
|
||||
req = requestWithBody("POST", "/", "test fail")
|
||||
assert.Error(t, p.Bind(req, &i))
|
||||
|
||||
req = requestWithBody("POST", "/", "")
|
||||
req.Body = &failRead{}
|
||||
assert.Error(t, p.Bind(req, &s))
|
||||
|
||||
req = requestWithBody("POST", "/", "")
|
||||
assert.Nil(t, p.Bind(req, nil))
|
||||
|
||||
var ptr *string
|
||||
req = requestWithBody("POST", "/", "")
|
||||
assert.Nil(t, p.Bind(req, ptr))
|
||||
}
|
||||
|
||||
func testProtoBodyBindingFail(t *testing.T, b Binding, name, path, badPath, body, badBody string) {
|
||||
assert.Equal(t, name, b.Name())
|
||||
|
||||
|
56
binding/plain.go
Normal file
56
binding/plain.go
Normal file
@ -0,0 +1,56 @@
|
||||
package binding
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"reflect"
|
||||
|
||||
"github.com/gin-gonic/gin/internal/bytesconv"
|
||||
)
|
||||
|
||||
type plainBinding struct{}
|
||||
|
||||
func (plainBinding) Name() string {
|
||||
return "plain"
|
||||
}
|
||||
|
||||
func (plainBinding) Bind(req *http.Request, obj interface{}) error {
|
||||
all, err := io.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return decodePlain(all, obj)
|
||||
}
|
||||
|
||||
func (plainBinding) BindBody(body []byte, obj any) error {
|
||||
return decodePlain(body, obj)
|
||||
}
|
||||
|
||||
func decodePlain(data []byte, obj any) error {
|
||||
if obj == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := reflect.ValueOf(obj)
|
||||
|
||||
for v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return nil
|
||||
}
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
if v.Kind() == reflect.String {
|
||||
v.SetString(bytesconv.BytesToString(data))
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, ok := v.Interface().([]byte); ok {
|
||||
v.SetBytes(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("type (%T) unknown type", v)
|
||||
}
|
Reference in New Issue
Block a user