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// Package mime implements parts of the MIME spec.
6package mime
7
8import (
9	"fmt"
10	"strings"
11	"sync"
12)
13
14var mimeTypes = map[string]string{
15	".css":  "text/css; charset=utf-8",
16	".gif":  "image/gif",
17	".htm":  "text/html; charset=utf-8",
18	".html": "text/html; charset=utf-8",
19	".jpg":  "image/jpeg",
20	".js":   "application/x-javascript",
21	".pdf":  "application/pdf",
22	".png":  "image/png",
23	".xml":  "text/xml; charset=utf-8",
24}
25
26var mimeLock sync.RWMutex
27
28var once sync.Once
29
30// TypeByExtension returns the MIME type associated with the file extension ext.
31// The extension ext should begin with a leading dot, as in ".html".
32// When ext has no associated type, TypeByExtension returns "".
33//
34// The built-in table is small but on unix it is augmented by the local
35// system's mime.types file(s) if available under one or more of these
36// names:
37//
38//   /etc/mime.types
39//   /etc/apache2/mime.types
40//   /etc/apache/mime.types
41//
42// Windows system mime types are extracted from registry.
43//
44// Text types have the charset parameter set to "utf-8" by default.
45func TypeByExtension(ext string) string {
46	once.Do(initMime)
47	mimeLock.RLock()
48	typename := mimeTypes[ext]
49	mimeLock.RUnlock()
50	return typename
51}
52
53// AddExtensionType sets the MIME type associated with
54// the extension ext to typ.  The extension should begin with
55// a leading dot, as in ".html".
56func AddExtensionType(ext, typ string) error {
57	if ext == "" || ext[0] != '.' {
58		return fmt.Errorf(`mime: extension "%s" misses dot`, ext)
59	}
60	once.Do(initMime)
61	return setExtensionType(ext, typ)
62}
63
64func setExtensionType(extension, mimeType string) error {
65	_, param, err := ParseMediaType(mimeType)
66	if err != nil {
67		return err
68	}
69	if strings.HasPrefix(mimeType, "text/") && param["charset"] == "" {
70		param["charset"] = "utf-8"
71		mimeType = FormatMediaType(mimeType, param)
72	}
73	mimeLock.Lock()
74	mimeTypes[extension] = mimeType
75	mimeLock.Unlock()
76	return nil
77}
78