github.com/System-Glitch/goyave/v2@v2.10.3-0.20200819142921-51011e75d504/helper/filesystem/filesystem.go (about) 1 package filesystem 2 3 import ( 4 "net/http" 5 "os" 6 "strconv" 7 "strings" 8 "time" 9 ) 10 11 var contentTypeByExtension map[string]string = map[string]string{ 12 ".jsonld": "application/ld+json", 13 ".json": "application/json", 14 ".js": "text/javascript", 15 ".mjs": "text/javascript", 16 ".css": "text/css", 17 } 18 19 // GetFileExtension returns the last part of a file name. 20 // If the file doesn't have an extension, returns an empty string. 21 func GetFileExtension(file string) string { 22 index := strings.LastIndex(file, ".") 23 if index == -1 { 24 return "" 25 } 26 return file[index+1:] 27 } 28 29 // GetMIMEType get the mime type and size of the given file. 30 // 31 // If the file cannot be opened, panics. You should check if the 32 // file exists, using "filesystem.FileExists()"", before calling this function. 33 func GetMIMEType(file string) (string, int64) { 34 f, err := os.Open(file) 35 if err != nil { 36 panic(err) 37 } 38 defer f.Close() 39 buffer := make([]byte, 512) 40 41 _, errRead := f.Read(buffer) 42 if errRead != nil { 43 panic(errRead) 44 } 45 46 stat, errStat := f.Stat() 47 if errStat != nil { 48 panic(errStat) 49 } 50 51 contentType := http.DetectContentType(buffer) 52 53 if strings.HasPrefix(contentType, "application/octet-stream") || strings.HasPrefix(contentType, "text/plain") { 54 for ext, t := range contentTypeByExtension { 55 if strings.HasSuffix(file, ext) { 56 tmp := t 57 if i := strings.Index(contentType, ";"); i != -1 { 58 tmp = t + contentType[i:] 59 } 60 contentType = tmp 61 break 62 } 63 } 64 } 65 66 return contentType, stat.Size() 67 } 68 69 // FileExists returns true if the file at the given path exists and is readable. 70 // Returns false if the given file is a directory 71 func FileExists(file string) bool { 72 if stats, err := os.Stat(file); err == nil { 73 return !stats.IsDir() 74 } 75 return false 76 } 77 78 // IsDirectory returns true if the file at the given path exists, is a directory and is readable. 79 func IsDirectory(path string) bool { 80 if stats, err := os.Stat(path); err == nil { 81 return stats.IsDir() 82 } 83 return false 84 } 85 86 // Delete the file at the given path. 87 // 88 // To avoid panics, you should check if the file exists. 89 func Delete(path string) { 90 err := os.Remove(path) 91 if err != nil { 92 panic(err) 93 } 94 } 95 96 // ParseMultipartFiles parse a single file field in a request. 97 func ParseMultipartFiles(request *http.Request, field string) []File { 98 files := []File{} 99 for _, fh := range request.MultipartForm.File[field] { 100 f, err := fh.Open() 101 if err != nil { 102 panic(err) 103 } 104 defer f.Close() 105 106 fileHeader := make([]byte, 512) 107 108 if _, err := f.Read(fileHeader); err != nil { 109 panic(err) 110 } 111 112 if _, err := f.Seek(0, 0); err != nil { 113 panic(err) 114 } 115 116 file := File{ 117 Header: fh, 118 MIMEType: http.DetectContentType(fileHeader), 119 Data: f, 120 } 121 files = append(files, file) 122 } 123 return files 124 } 125 126 func timestampFileName(name string) string { 127 var prefix string 128 var extension string 129 index := strings.LastIndex(name, ".") 130 if index == -1 { 131 prefix = name 132 extension = "" 133 } else { 134 prefix = name[:index] 135 extension = name[index:] 136 } 137 return prefix + "-" + strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10) + extension 138 }