goyave.dev/goyave/v4@v4.4.11/util/fsutil/file.go (about)

     1  package fsutil
     2  
     3  import (
     4  	"io"
     5  	"mime/multipart"
     6  	"net/http"
     7  	"os"
     8  )
     9  
    10  // File represents a file received from client.
    11  type File struct {
    12  	Data     multipart.File
    13  	Header   *multipart.FileHeader
    14  	MIMEType string
    15  }
    16  
    17  // Save writes the given file on the disk.
    18  // Appends a timestamp to the given file name to avoid duplicate file names.
    19  // The file is not readable anymore once saved as its FileReader has already been
    20  // closed.
    21  //
    22  // Creates directories if needed.
    23  //
    24  // Returns the actual file name.
    25  func (file *File) Save(path string, name string) string {
    26  	name = timestampFileName(name)
    27  	if err := os.MkdirAll(path, os.ModePerm); err != nil {
    28  		panic(err)
    29  	}
    30  	writer, err := os.OpenFile(path+string(os.PathSeparator)+name, os.O_WRONLY|os.O_CREATE, 0660)
    31  	if err != nil {
    32  		panic(err)
    33  	}
    34  	defer writer.Close()
    35  	_, errCopy := io.Copy(writer, file.Data)
    36  	if errCopy != nil {
    37  		panic(errCopy)
    38  	}
    39  	file.Data.Close()
    40  	return name
    41  }
    42  
    43  // ParseMultipartFiles parse a single file field in a request.
    44  func ParseMultipartFiles(request *http.Request, field string) []File {
    45  	files := []File{}
    46  	for _, fh := range request.MultipartForm.File[field] {
    47  		f, err := fh.Open()
    48  		if err != nil {
    49  			panic(err)
    50  		}
    51  		defer f.Close()
    52  
    53  		fileHeader := make([]byte, 512)
    54  
    55  		if fh.Size != 0 {
    56  			if _, err := f.Read(fileHeader); err != nil {
    57  				panic(err)
    58  			}
    59  
    60  			if _, err := f.Seek(0, 0); err != nil {
    61  				panic(err)
    62  			}
    63  		}
    64  
    65  		file := File{
    66  			Header:   fh,
    67  			MIMEType: http.DetectContentType(fileHeader),
    68  			Data:     f,
    69  		}
    70  		files = append(files, file)
    71  	}
    72  	return files
    73  }