diff --git a/README.md b/README.md index b6020a2e..92d6a0ba 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,47 @@ func main() { } ``` +###Multipart Form +```go +package main + +import ( + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" +) + +type LoginForm struct { + User string `form:"user" binding:"required"` + Password string `form:"password" binding:"required"` +} + +func main() { + + r := gin.Default() + + r.POST("/login", func(c *gin.Context) { + + var form LoginForm + c.BindWith(&form, binding.MultipartForm) + + if form.User == "user" && form.Password == "password" { + c.JSON(200, gin.H{"status": "you are logged in"}) + } else { + c.JSON(401, gin.H{"status": "unauthorized"}) + } + + }) + + r.Run(":8080") + +} +``` + +Test it with: +```bash +$ curl -v --form user=user --form password=password http://localhost:8080/login +``` + #### Grouping routes ```go func main() { diff --git a/binding/binding.go b/binding/binding.go index b49f1e5c..f72b9434 100644 --- a/binding/binding.go +++ b/binding/binding.go @@ -25,14 +25,20 @@ type ( // XML binding xmlBinding struct{} - // // form binding + // form binding formBinding struct{} + + // multipart form binding + multipartFormBinding struct{} ) +const MAX_MEMORY = 1 * 1024 * 1024 + var ( - JSON = jsonBinding{} - XML = xmlBinding{} - Form = formBinding{} // todo + JSON = jsonBinding{} + XML = xmlBinding{} + Form = formBinding{} // todo + MultipartForm = multipartFormBinding{} ) func (_ jsonBinding) Bind(req *http.Request, obj interface{}) error { @@ -63,6 +69,16 @@ func (_ formBinding) Bind(req *http.Request, obj interface{}) error { return Validate(obj) } +func (_ multipartFormBinding) Bind(req *http.Request, obj interface{}) error { + if err := req.ParseMultipartForm(MAX_MEMORY); err != nil { + return err + } + if err := mapForm(obj, req.Form); err != nil { + return err + } + return Validate(obj) +} + func mapForm(ptr interface{}, form map[string][]string) error { typ := reflect.TypeOf(ptr).Elem() formStruct := reflect.ValueOf(ptr).Elem() diff --git a/context.go b/context.go index c39d5e26..d8775142 100644 --- a/context.go +++ b/context.go @@ -295,6 +295,8 @@ func (c *Context) Bind(obj interface{}) bool { switch { case c.Request.Method == "GET" || ctype == MIMEPOSTForm: b = binding.Form + case ctype == MIMEMultipartPOSTForm: + b = binding.MultipartForm case ctype == MIMEJSON: b = binding.JSON case ctype == MIMEXML || ctype == MIMEXML2: diff --git a/gin.go b/gin.go index 42c4b1f6..3e7181cf 100644 --- a/gin.go +++ b/gin.go @@ -14,13 +14,14 @@ import ( ) const ( - AbortIndex = math.MaxInt8 / 2 - MIMEJSON = "application/json" - MIMEHTML = "text/html" - MIMEXML = "application/xml" - MIMEXML2 = "text/xml" - MIMEPlain = "text/plain" - MIMEPOSTForm = "application/x-www-form-urlencoded" + AbortIndex = math.MaxInt8 / 2 + MIMEJSON = "application/json" + MIMEHTML = "text/html" + MIMEXML = "application/xml" + MIMEXML2 = "text/xml" + MIMEPlain = "text/plain" + MIMEPOSTForm = "application/x-www-form-urlencoded" + MIMEMultipartPOSTForm = "multipart/form-data" ) type (