mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-18 23:12:17 +08:00
binding: add BindPlain function
```go package main import ( "github.com/gin-gonic/gin" ) func main() { router := gin.Default() router.POST("/", func(c *gin.Context) { var s string c.BindPlain(&s) c.String(200, s) }) router.Run() } // client // curl -d "test string" 127.0.0.1:8080 // output // test string ```
This commit is contained in:
parent
01ca625b98
commit
53df00ffe4
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
*~
|
||||
vendor/*
|
||||
!vendor/vendor.json
|
||||
coverage.out
|
||||
|
@ -79,6 +79,7 @@ var (
|
||||
YAML = yamlBinding{}
|
||||
Uri = uriBinding{}
|
||||
Header = headerBinding{}
|
||||
Plain = plainBinding{}
|
||||
)
|
||||
|
||||
// Default returns the appropriate Binding instance based on the HTTP method
|
||||
@ -101,6 +102,8 @@ func Default(method, contentType string) Binding {
|
||||
return YAML
|
||||
case MIMEMultipartPOSTForm:
|
||||
return FormMultipart
|
||||
case MIMEPlain:
|
||||
return Plain
|
||||
default: // case MIMEPOSTForm:
|
||||
return Form
|
||||
}
|
||||
|
@ -156,6 +156,9 @@ func TestBindingDefault(t *testing.T) {
|
||||
assert.Equal(t, FormMultipart, Default("POST", MIMEMultipartPOSTForm))
|
||||
assert.Equal(t, FormMultipart, Default("PUT", MIMEMultipartPOSTForm))
|
||||
|
||||
assert.Equal(t, Plain, Default("POST", MIMEPlain))
|
||||
assert.Equal(t, Plain, Default("PUT", MIMEPlain))
|
||||
|
||||
assert.Equal(t, ProtoBuf, Default("POST", MIMEPROTOBUF))
|
||||
assert.Equal(t, ProtoBuf, Default("PUT", MIMEPROTOBUF))
|
||||
|
||||
@ -680,6 +683,46 @@ func TestExistsFails(t *testing.T) {
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
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 TestHeaderBinding(t *testing.T) {
|
||||
h := Header
|
||||
assert.Equal(t, "header", h.Name())
|
||||
|
47
binding/plain.go
Normal file
47
binding/plain.go
Normal file
@ -0,0 +1,47 @@
|
||||
package binding
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type plainBinding struct{}
|
||||
|
||||
func (plainBinding) Name() string {
|
||||
return "plain"
|
||||
}
|
||||
|
||||
func (plainBinding) Bind(req *http.Request, obj interface{}) error {
|
||||
if obj == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
v := reflect.ValueOf(obj)
|
||||
|
||||
for v.Kind() == reflect.Ptr {
|
||||
if v.IsNil() {
|
||||
return nil
|
||||
}
|
||||
v = v.Elem()
|
||||
}
|
||||
|
||||
all, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if v.Kind() == reflect.String {
|
||||
v.SetString(*(*string)(unsafe.Pointer(&all)))
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, ok := v.Interface().([]byte); ok {
|
||||
v.SetBytes(all)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("type (%T) unkown type", v)
|
||||
}
|
10
context.go
10
context.go
@ -583,6 +583,11 @@ func (c *Context) BindYAML(obj interface{}) error {
|
||||
return c.MustBindWith(obj, binding.YAML)
|
||||
}
|
||||
|
||||
// BindHeader is a shortcut for c.MustBindWith(obj, binding.Plain).
|
||||
func (c *Context) BindPlain(obj interface{}) error {
|
||||
return c.MustBindWith(obj, binding.Plain)
|
||||
}
|
||||
|
||||
// BindHeader is a shortcut for c.MustBindWith(obj, binding.Header).
|
||||
func (c *Context) BindHeader(obj interface{}) error {
|
||||
return c.MustBindWith(obj, binding.Header)
|
||||
@ -642,6 +647,11 @@ func (c *Context) ShouldBindYAML(obj interface{}) error {
|
||||
return c.ShouldBindWith(obj, binding.YAML)
|
||||
}
|
||||
|
||||
// ShouldBindPlain is a shortcut for c.ShouldBindWith(obj, binding.Header).
|
||||
func (c *Context) ShouldBindPlain(obj interface{}) error {
|
||||
return c.ShouldBindWith(obj, binding.Plain)
|
||||
}
|
||||
|
||||
// ShouldBindHeader is a shortcut for c.ShouldBindWith(obj, binding.Header).
|
||||
func (c *Context) ShouldBindHeader(obj interface{}) error {
|
||||
return c.ShouldBindWith(obj, binding.Header)
|
||||
|
@ -1436,6 +1436,30 @@ func TestContextBindWithXML(t *testing.T) {
|
||||
assert.Equal(t, 0, w.Body.Len())
|
||||
}
|
||||
|
||||
func TestContextBindPlain(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test string`))
|
||||
c.Request.Header.Add("Content-Type", MIMEPlain)
|
||||
|
||||
var s string
|
||||
|
||||
assert.NoError(t, c.BindPlain(&s))
|
||||
assert.Equal(t, "test string", s)
|
||||
assert.Equal(t, 0, w.Body.Len())
|
||||
// ========================
|
||||
|
||||
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test []byte`))
|
||||
c.Request.Header.Add("Content-Type", MIMEPlain)
|
||||
|
||||
var bs []byte
|
||||
|
||||
assert.NoError(t, c.BindPlain(&bs))
|
||||
assert.Equal(t, []byte("test []byte"), bs)
|
||||
assert.Equal(t, 0, w.Body.Len())
|
||||
|
||||
}
|
||||
|
||||
func TestContextBindHeader(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
@ -1565,6 +1589,29 @@ func TestContextShouldBindWithXML(t *testing.T) {
|
||||
assert.Equal(t, 0, w.Body.Len())
|
||||
}
|
||||
|
||||
func TestContextShouldBindPlain(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test string`))
|
||||
c.Request.Header.Add("Content-Type", MIMEPlain)
|
||||
|
||||
var s string
|
||||
|
||||
assert.NoError(t, c.ShouldBindPlain(&s))
|
||||
assert.Equal(t, "test string", s)
|
||||
assert.Equal(t, 0, w.Body.Len())
|
||||
// ========================
|
||||
|
||||
c.Request, _ = http.NewRequest("POST", "/", bytes.NewBufferString(`test []byte`))
|
||||
c.Request.Header.Add("Content-Type", MIMEPlain)
|
||||
|
||||
var bs []byte
|
||||
|
||||
assert.NoError(t, c.BindPlain(&bs))
|
||||
assert.Equal(t, []byte("test []byte"), bs)
|
||||
assert.Equal(t, 0, w.Body.Len())
|
||||
|
||||
}
|
||||
func TestContextShouldBindHeader(t *testing.T) {
|
||||
w := httptest.NewRecorder()
|
||||
c, _ := CreateTestContext(w)
|
||||
|
Loading…
x
Reference in New Issue
Block a user