From: Pascal S. de Kloe Date: Fri, 26 Aug 2011 20:55:25 +0000 (-0400) Subject: mime: text charset defaults X-Git-Tag: weekly.2011-09-01~61 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=bd3627cd7de3fd5d9640c19bcbe270b9e8056e39;p=gostls13.git mime: text charset defaults Enforce + document the UTF-8 default. R=rsc, bradfitz, adg CC=golang-dev https://golang.org/cl/4627049 --- diff --git a/src/pkg/mime/type.go b/src/pkg/mime/type.go index 8ecfe9a37b..deb0ff6d91 100644 --- a/src/pkg/mime/type.go +++ b/src/pkg/mime/type.go @@ -7,6 +7,7 @@ package mime import ( "bufio" + "fmt" "os" "strings" "sync" @@ -19,15 +20,15 @@ var typeFiles = []string{ } var mimeTypes = map[string]string{ - ".css": "text/css; charset=utf-8", + ".css": "text/css;charset=utf-8", ".gif": "image/gif", - ".htm": "text/html; charset=utf-8", - ".html": "text/html; charset=utf-8", + ".htm": "text/html;charset=utf-8", + ".html": "text/html;charset=utf-8", ".jpg": "image/jpeg", ".js": "application/x-javascript", ".pdf": "application/pdf", ".png": "image/png", - ".xml": "text/xml; charset=utf-8", + ".xml": "text/xml;charset=utf-8", } var mimeLock sync.RWMutex @@ -49,15 +50,12 @@ func loadMimeFile(filename string) { if len(fields) <= 1 || fields[0][0] == '#' { continue } - typename := fields[0] - if strings.HasPrefix(typename, "text/") { - typename += "; charset=utf-8" - } + mimeType := fields[0] for _, ext := range fields[1:] { if ext[0] == '#' { break } - mimeTypes["."+ext] = typename + setExtensionType("."+ext, mimeType) } } } @@ -81,6 +79,8 @@ var once sync.Once // /etc/mime.types // /etc/apache2/mime.types // /etc/apache/mime.types +// +// Text types have the charset parameter set to "utf-8" by default. func TypeByExtension(ext string) string { once.Do(initMime) mimeLock.RLock() @@ -93,12 +93,31 @@ func TypeByExtension(ext string) string { // the extension ext to typ. The extension should begin with // a leading dot, as in ".html". func AddExtensionType(ext, typ string) os.Error { + if ext == "" || ext[0] != '.' { + return fmt.Errorf(`mime: extension "%s" misses dot`, ext) + } once.Do(initMime) - if len(ext) < 1 || ext[0] != '.' { - return os.EINVAL + return setExtensionType(ext, typ) +} + +func setExtensionType(extension, mimeType string) os.Error { + full, param, err := ParseMediaType(mimeType) + if err != nil { + return err + } + if split := strings.Index(full, "/"); split < 0 { + return fmt.Errorf(`mime: malformed MIME type "%s"`, mimeType) + } else { + main := full[:split] + sub := full[split+1:] + if main == "text" && param["charset"] == "" { + param["charset"] = "utf-8" + } + mimeType = FormatMediaType(main, sub, param) } + mimeLock.Lock() - mimeTypes[ext] = typ + mimeTypes[extension] = mimeType mimeLock.Unlock() return nil } diff --git a/src/pkg/mime/mime_test.go b/src/pkg/mime/type_test.go similarity index 53% rename from src/pkg/mime/mime_test.go rename to src/pkg/mime/type_test.go index 17e610443e..2af39c7bb8 100644 --- a/src/pkg/mime/mime_test.go +++ b/src/pkg/mime/type_test.go @@ -2,19 +2,17 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Tests for type.go - package mime import "testing" var typeTests = map[string]string{ ".t1": "application/test", - ".t2": "text/test; charset=utf-8", + ".t2": "text/test;charset=utf-8", ".png": "image/png", } -func TestType(t *testing.T) { +func TestTypeByExtension(t *testing.T) { typeFiles = []string{"test.types"} for ext, want := range typeTests { @@ -25,3 +23,13 @@ func TestType(t *testing.T) { } } + +func TestCustomExtension(t *testing.T) { + custom := "text/xml;charset=iso-8859-1" + if error := AddExtensionType(".xml", custom); error != nil { + t.Fatalf("error %s for AddExtension(%s)", error, custom) + } + if registered := TypeByExtension(".xml"); registered != custom { + t.Fatalf("registered %s instead of %s", registered, custom) + } +}