github.com/jacobsoderblom/buffalo@v0.11.0/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  }