form.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. // Copyright 2014 Manu Martinez-Almeida. All rights reserved.
  2. // Use of this source code is governed by a MIT style
  3. // license that can be found in the LICENSE file.
  4. package binding
  5. import (
  6. "mime/multipart"
  7. "net/http"
  8. "reflect"
  9. )
  10. const defaultMemory = 32 * 1024 * 1024
  11. type formBinding struct{}
  12. type formPostBinding struct{}
  13. type formMultipartBinding struct{}
  14. func (formBinding) Name() string {
  15. return "form"
  16. }
  17. func (formBinding) Bind(req *http.Request, obj interface{}) error {
  18. if err := req.ParseForm(); err != nil {
  19. return err
  20. }
  21. if err := req.ParseMultipartForm(defaultMemory); err != nil {
  22. if err != http.ErrNotMultipart {
  23. return err
  24. }
  25. }
  26. if err := mapForm(obj, req.Form); err != nil {
  27. return err
  28. }
  29. return validate(obj)
  30. }
  31. func (formPostBinding) Name() string {
  32. return "form-urlencoded"
  33. }
  34. func (formPostBinding) Bind(req *http.Request, obj interface{}) error {
  35. if err := req.ParseForm(); err != nil {
  36. return err
  37. }
  38. if err := mapForm(obj, req.PostForm); err != nil {
  39. return err
  40. }
  41. return validate(obj)
  42. }
  43. func (formMultipartBinding) Name() string {
  44. return "multipart/form-data"
  45. }
  46. func (formMultipartBinding) Bind(req *http.Request, obj interface{}) error {
  47. if err := req.ParseMultipartForm(defaultMemory); err != nil {
  48. return err
  49. }
  50. if err := mappingByPtr(obj, (*multipartRequest)(req), "form"); err != nil {
  51. return err
  52. }
  53. return validate(obj)
  54. }
  55. type multipartRequest http.Request
  56. var _ setter = (*multipartRequest)(nil)
  57. var (
  58. multipartFileHeaderStructType = reflect.TypeOf(multipart.FileHeader{})
  59. )
  60. // TrySet tries to set a value by the multipart request with the binding a form file
  61. func (r *multipartRequest) TrySet(value reflect.Value, field reflect.StructField, key string, opt setOptions) (isSetted bool, err error) {
  62. if value.Type() == multipartFileHeaderStructType {
  63. _, file, err := (*http.Request)(r).FormFile(key)
  64. if err != nil {
  65. return false, err
  66. }
  67. if file != nil {
  68. value.Set(reflect.ValueOf(*file))
  69. return true, nil
  70. }
  71. }
  72. return setByForm(value, field, r.MultipartForm.Value, key, opt)
  73. }