Skip to content

Commit 3e8ba91

Browse files
Jacalzianlancetaylor
authored andcommitted
mime: support reading shared mime-info database on unix systems
This adds support for reading the FreeDesktop Shared MIME-info Database on Unix systems, if it exists. It should make lookups work on systems where the mime.types files are not present and should lead to better mimetype lookup in general. If the shared mimetype database does not exist, we will fall back to reading mime.types files in common locations. Related to a bug on Solus bugtracker: https://dev.getsol.us/T9394 This change makes the mime package work on Solus. Change-Id: If330c22ffe523bf31f7f10807a54fc8858517055 GitHub-Last-Rev: d5fbe8c GitHub-Pull-Request: #45271 Reviewed-on: https://go-review.googlesource.com/c/go/+/305230 Run-TryBot: Ian Lance Taylor <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Trust: Tobias Klauser <[email protected]>
1 parent 1b736b3 commit 3e8ba91

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

src/mime/testdata/test.types.globs2

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright 2021 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+
6+
# mime package test for globs2
7+
50:document/test:*.t3
8+
50:example/test:*.t4

src/mime/type_unix.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,46 @@ func init() {
1717
osInitMime = initMimeUnix
1818
}
1919

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.
2028
var typeFiles = []string{
2129
"/etc/mime.types",
2230
"/etc/apache2/mime.types",
2331
"/etc/apache/mime.types",
2432
"/etc/httpd/conf/mime.types",
2533
}
2634

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+
setExtensionType(fields[2][1:], fields[1])
53+
}
54+
if err := scanner.Err(); err != nil {
55+
panic(err)
56+
}
57+
return nil
58+
}
59+
2760
func loadMimeFile(filename string) {
2861
f, err := os.Open(filename)
2962
if err != nil {
@@ -51,12 +84,20 @@ func loadMimeFile(filename string) {
5184
}
5285

5386
func initMimeUnix() {
87+
for _, filename := range mimeGlobs {
88+
if err := loadMimeGlobsFile(filename); err == nil {
89+
return // Stop checking more files if mimetype database is found.
90+
}
91+
}
92+
93+
// Fallback if no system-generated mimetype database exists.
5494
for _, filename := range typeFiles {
5595
loadMimeFile(filename)
5696
}
5797
}
5898

5999
func initMimeForTests() map[string]string {
100+
mimeGlobs = []string{""}
60101
typeFiles = []string{"testdata/test.types"}
61102
return map[string]string{
62103
".T1": "application/test",

src/mime/type_unix_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2021 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+
"testing"
12+
)
13+
14+
func initMimeUnixTest(t *testing.T) {
15+
err := loadMimeGlobsFile("testdata/test.types.globs2")
16+
if err != nil {
17+
t.Fatal(err)
18+
}
19+
20+
loadMimeFile("testdata/test.types")
21+
}
22+
23+
func TestTypeByExtensionUNIX(t *testing.T) {
24+
initMimeUnixTest(t)
25+
typeTests := map[string]string{
26+
".T1": "application/test",
27+
".t2": "text/test; charset=utf-8",
28+
".t3": "document/test",
29+
".t4": "example/test",
30+
".png": "image/png",
31+
}
32+
33+
for ext, want := range typeTests {
34+
val := TypeByExtension(ext)
35+
if val != want {
36+
t.Errorf("TypeByExtension(%q) = %q, want %q", ext, val, want)
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)