github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/mime/type_unix.go (about) 1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris 6 7 package mime 8 9 import ( 10 "bufio" 11 "os" 12 "strings" 13 ) 14 15 func init() { 16 osInitMime = initMimeUnix 17 } 18 19 // See https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-0.21.html 20 // for the FreeDesktop Shared MIME-info Database specification. 21 var mimeGlobs = []string{ 22 "/usr/local/share/mime/globs2", 23 "/usr/share/mime/globs2", 24 } 25 26 // Common locations for mime.types files on unix. 27 var typeFiles = []string{ 28 "/etc/mime.types", 29 "/etc/apache2/mime.types", 30 "/etc/apache/mime.types", 31 "/etc/httpd/conf/mime.types", 32 } 33 34 func loadMimeGlobsFile(filename string) error { 35 f, err := os.Open(filename) 36 if err != nil { 37 return err 38 } 39 defer f.Close() 40 41 scanner := bufio.NewScanner(f) 42 for scanner.Scan() { 43 // Each line should be of format: weight:mimetype:*.ext 44 fields := strings.Split(scanner.Text(), ":") 45 if len(fields) < 3 || len(fields[0]) < 1 || len(fields[2]) < 2 { 46 continue 47 } else if fields[0][0] == '#' || fields[2][0] != '*' { 48 continue 49 } 50 51 extension := fields[2][1:] 52 if _, ok := mimeTypes.Load(extension); ok { 53 // We've already seen this extension. 54 // The file is in weight order, so we keep 55 // the first entry that we see. 56 continue 57 } 58 59 setExtensionType(extension, fields[1]) 60 } 61 if err := scanner.Err(); err != nil { 62 panic(err) 63 } 64 return nil 65 } 66 67 func loadMimeFile(filename string) { 68 f, err := os.Open(filename) 69 if err != nil { 70 return 71 } 72 defer f.Close() 73 74 scanner := bufio.NewScanner(f) 75 for scanner.Scan() { 76 fields := strings.Fields(scanner.Text()) 77 if len(fields) <= 1 || fields[0][0] == '#' { 78 continue 79 } 80 mimeType := fields[0] 81 for _, ext := range fields[1:] { 82 if ext[0] == '#' { 83 break 84 } 85 setExtensionType("."+ext, mimeType) 86 } 87 } 88 if err := scanner.Err(); err != nil { 89 panic(err) 90 } 91 } 92 93 func initMimeUnix() { 94 for _, filename := range mimeGlobs { 95 if err := loadMimeGlobsFile(filename); err == nil { 96 return // Stop checking more files if mimetype database is found. 97 } 98 } 99 100 // Fallback if no system-generated mimetype database exists. 101 for _, filename := range typeFiles { 102 loadMimeFile(filename) 103 } 104 } 105 106 func initMimeForTests() map[string]string { 107 mimeGlobs = []string{""} 108 typeFiles = []string{"testdata/test.types"} 109 return map[string]string{ 110 ".T1": "application/test", 111 ".t2": "text/test; charset=utf-8", 112 ".png": "image/png", 113 } 114 }