mirror of
https://github.com/gin-gonic/gin.git
synced 2025-10-19 15:57:48 +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/vendor.json
|
!vendor/vendor.json
|
||||||
coverage.out
|
coverage.out
|
||||||
|
@ -79,6 +79,7 @@ var (
|
|||||||
YAML = yamlBinding{}
|
YAML = yamlBinding{}
|
||||||
Uri = uriBinding{}
|
Uri = uriBinding{}
|
||||||
Header = headerBinding{}
|
Header = headerBinding{}
|
||||||
|
Plain = plainBinding{}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Default returns the appropriate Binding instance based on the HTTP method
|
// Default returns the appropriate Binding instance based on the HTTP method
|
||||||
@ -101,6 +102,8 @@ func Default(method, contentType string) Binding {
|
|||||||
return YAML
|
return YAML
|
||||||
case MIMEMultipartPOSTForm:
|
case MIMEMultipartPOSTForm:
|
||||||
return FormMultipart
|
return FormMultipart
|
||||||
|
case MIMEPlain:
|
||||||
|
return Plain
|
||||||
default: // case MIMEPOSTForm:
|
default: // case MIMEPOSTForm:
|
||||||
return Form
|
return Form
|
||||||
}
|
}
|
||||||
|
@ -156,6 +156,9 @@ func TestBindingDefault(t *testing.T) {
|
|||||||
assert.Equal(t, FormMultipart, Default("POST", MIMEMultipartPOSTForm))
|
assert.Equal(t, FormMultipart, Default("POST", MIMEMultipartPOSTForm))
|
||||||
assert.Equal(t, FormMultipart, Default("PUT", 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("POST", MIMEPROTOBUF))
|
||||||
assert.Equal(t, ProtoBuf, Default("PUT", MIMEPROTOBUF))
|
assert.Equal(t, ProtoBuf, Default("PUT", MIMEPROTOBUF))
|
||||||
|
|
||||||
@ -680,6 +683,46 @@ func TestExistsFails(t *testing.T) {
|
|||||||
assert.Error(t, err)
|
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) {
|
func TestHeaderBinding(t *testing.T) {
|
||||||
h := Header
|
h := Header
|
||||||
assert.Equal(t, "header", h.Name())
|
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)
|
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).
|
// BindHeader is a shortcut for c.MustBindWith(obj, binding.Header).
|
||||||
func (c *Context) BindHeader(obj interface{}) error {
|
func (c *Context) BindHeader(obj interface{}) error {
|
||||||
return c.MustBindWith(obj, binding.Header)
|
return c.MustBindWith(obj, binding.Header)
|
||||||
@ -642,6 +647,11 @@ func (c *Context) ShouldBindYAML(obj interface{}) error {
|
|||||||
return c.ShouldBindWith(obj, binding.YAML)
|
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).
|
// ShouldBindHeader is a shortcut for c.ShouldBindWith(obj, binding.Header).
|
||||||
func (c *Context) ShouldBindHeader(obj interface{}) error {
|
func (c *Context) ShouldBindHeader(obj interface{}) error {
|
||||||
return c.ShouldBindWith(obj, binding.Header)
|
return c.ShouldBindWith(obj, binding.Header)
|
||||||
|
@ -1436,6 +1436,30 @@ func TestContextBindWithXML(t *testing.T) {
|
|||||||
assert.Equal(t, 0, w.Body.Len())
|
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) {
|
func TestContextBindHeader(t *testing.T) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
@ -1565,6 +1589,29 @@ func TestContextShouldBindWithXML(t *testing.T) {
|
|||||||
assert.Equal(t, 0, w.Body.Len())
|
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) {
|
func TestContextShouldBindHeader(t *testing.T) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, _ := CreateTestContext(w)
|
c, _ := CreateTestContext(w)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user