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