github.com/res-am/buffalo@v0.11.1/binding/file.go (about) 1 package binding 2 3 import ( 4 "mime/multipart" 5 "net/http" 6 "reflect" 7 8 "github.com/pkg/errors" 9 ) 10 11 // MaxFileMemory can be used to set the maximum size, in bytes, for files to be 12 // stored in memory during uploaded for multipart requests. 13 // See https://golang.org/pkg/net/http/#Request.ParseMultipartForm for more 14 // information on how this impacts file uploads. 15 var MaxFileMemory int64 = 5 * 1024 * 1024 16 17 // File holds information regarding an uploaded file 18 type File struct { 19 multipart.File 20 *multipart.FileHeader 21 } 22 23 // Valid if there is an actual uploaded file 24 func (f File) Valid() bool { 25 if f.File == nil { 26 return false 27 } 28 return true 29 } 30 31 func (f File) String() string { 32 if f.File == nil { 33 return "" 34 } 35 return f.Filename 36 } 37 38 func init() { 39 sb := func(req *http.Request, i interface{}) error { 40 err := req.ParseMultipartForm(MaxFileMemory) 41 if err != nil { 42 return errors.WithStack(err) 43 } 44 if err := decoder.Decode(req.Form, i); err != nil { 45 return errors.WithStack(err) 46 } 47 48 form := req.MultipartForm.File 49 if len(form) == 0 { 50 return nil 51 } 52 53 ri := reflect.Indirect(reflect.ValueOf(i)) 54 rt := ri.Type() 55 for n := range form { 56 f := ri.FieldByName(n) 57 if !f.IsValid() { 58 for i := 0; i < rt.NumField(); i++ { 59 sf := rt.Field(i) 60 if sf.Tag.Get("form") == n { 61 f = ri.Field(i) 62 break 63 } 64 } 65 } 66 if !f.IsValid() { 67 continue 68 } 69 if _, ok := f.Interface().(File); !ok { 70 continue 71 } 72 mf, mh, err := req.FormFile(n) 73 if err != nil { 74 return errors.WithStack(err) 75 } 76 f.Set(reflect.ValueOf(File{ 77 File: mf, 78 FileHeader: mh, 79 })) 80 } 81 82 return nil 83 } 84 binders["multipart/form-data"] = sb 85 }