aboutsummaryrefslogtreecommitdiff
path: root/src/mime
diff options
context:
space:
mode:
authorJacalz <jacob.alzen@gmail.com>2021-04-09 14:57:59 +0000
committerIan Lance Taylor <iant@golang.org>2021-04-12 21:04:48 +0000
commit3e8ba91275cdeb0af4c8b30f9cc788fd42cfbbd3 (patch)
tree0dddd00ba8fc1b91fa19b29380e5117b1080c449 /src/mime
parent1b736b3c19375f6ebd0d834c02316fb13700be27 (diff)
downloadgo-3e8ba91275cdeb0af4c8b30f9cc788fd42cfbbd3.tar.gz
go-3e8ba91275cdeb0af4c8b30f9cc788fd42cfbbd3.zip
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: d5fbe8c41a9d975029b35498183a0f5a40df8e6a GitHub-Pull-Request: golang/go#45271 Reviewed-on: https://go-review.googlesource.com/c/go/+/305230 Run-TryBot: Ian Lance Taylor <iant@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Trust: Tobias Klauser <tobias.klauser@gmail.com>
Diffstat (limited to 'src/mime')
-rw-r--r--src/mime/testdata/test.types.globs28
-rw-r--r--src/mime/type_unix.go41
-rw-r--r--src/mime/type_unix_test.go39
3 files changed, 88 insertions, 0 deletions
diff --git a/src/mime/testdata/test.types.globs2 b/src/mime/testdata/test.types.globs2
new file mode 100644
index 0000000000..2e893262ea
--- /dev/null
+++ b/src/mime/testdata/test.types.globs2
@@ -0,0 +1,8 @@
+# Copyright 2021 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+
+# mime package test for globs2
+50:document/test:*.t3
+50:example/test:*.t4
diff --git a/src/mime/type_unix.go b/src/mime/type_unix.go
index 851d5a0fb0..59c99e2c86 100644
--- a/src/mime/type_unix.go
+++ b/src/mime/type_unix.go
@@ -17,6 +17,14 @@ func init() {
osInitMime = initMimeUnix
}
+// See https://specifications.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-0.21.html
+// for the FreeDesktop Shared MIME-info Database specification.
+var mimeGlobs = []string{
+ "/usr/local/share/mime/globs2",
+ "/usr/share/mime/globs2",
+}
+
+// Common locations for mime.types files on unix.
var typeFiles = []string{
"/etc/mime.types",
"/etc/apache2/mime.types",
@@ -24,6 +32,31 @@ var typeFiles = []string{
"/etc/httpd/conf/mime.types",
}
+func loadMimeGlobsFile(filename string) error {
+ f, err := os.Open(filename)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ scanner := bufio.NewScanner(f)
+ for scanner.Scan() {
+ // Each line should be of format: weight:mimetype:*.ext
+ fields := strings.Split(scanner.Text(), ":")
+ if len(fields) < 3 || len(fields[0]) < 1 || len(fields[2]) < 2 {
+ continue
+ } else if fields[0][0] == '#' || fields[2][0] != '*' {
+ continue
+ }
+
+ setExtensionType(fields[2][1:], fields[1])
+ }
+ if err := scanner.Err(); err != nil {
+ panic(err)
+ }
+ return nil
+}
+
func loadMimeFile(filename string) {
f, err := os.Open(filename)
if err != nil {
@@ -51,12 +84,20 @@ func loadMimeFile(filename string) {
}
func initMimeUnix() {
+ for _, filename := range mimeGlobs {
+ if err := loadMimeGlobsFile(filename); err == nil {
+ return // Stop checking more files if mimetype database is found.
+ }
+ }
+
+ // Fallback if no system-generated mimetype database exists.
for _, filename := range typeFiles {
loadMimeFile(filename)
}
}
func initMimeForTests() map[string]string {
+ mimeGlobs = []string{""}
typeFiles = []string{"testdata/test.types"}
return map[string]string{
".T1": "application/test",
diff --git a/src/mime/type_unix_test.go b/src/mime/type_unix_test.go
new file mode 100644
index 0000000000..6e2988225c
--- /dev/null
+++ b/src/mime/type_unix_test.go
@@ -0,0 +1,39 @@
+// Copyright 2021 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || (js && wasm) || linux || netbsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solaris
+
+package mime
+
+import (
+ "testing"
+)
+
+func initMimeUnixTest(t *testing.T) {
+ err := loadMimeGlobsFile("testdata/test.types.globs2")
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ loadMimeFile("testdata/test.types")
+}
+
+func TestTypeByExtensionUNIX(t *testing.T) {
+ initMimeUnixTest(t)
+ typeTests := map[string]string{
+ ".T1": "application/test",
+ ".t2": "text/test; charset=utf-8",
+ ".t3": "document/test",
+ ".t4": "example/test",
+ ".png": "image/png",
+ }
+
+ for ext, want := range typeTests {
+ val := TypeByExtension(ext)
+ if val != want {
+ t.Errorf("TypeByExtension(%q) = %q, want %q", ext, val, want)
+ }
+ }
+}