blob: 00cff263bad95646190c43d735584526d6e610d7 [file] [log] [blame]
Michael Hoisie0cba5fc2010-02-09 20:47:45 -08001// 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
Nigel Tao6a186d32011-04-20 09:57:05 +10005// Package mime implements parts of the MIME spec.
Michael Hoisie0cba5fc2010-02-09 20:47:45 -08006package mime
7
8import (
Pascal S. de Kloebd3627c2011-08-26 16:55:25 -04009 "fmt"
Michael Hoisie0cba5fc2010-02-09 20:47:45 -080010 "strings"
Yuusei Kuwanac21e2f32010-07-29 14:12:04 -070011 "sync"
Michael Hoisie0cba5fc2010-02-09 20:47:45 -080012)
13
Michael Hoisie0cba5fc2010-02-09 20:47:45 -080014var mimeTypes = map[string]string{
Russ Cox91643ac2011-08-26 17:19:52 -040015 ".css": "text/css; charset=utf-8",
Robert Griesemerf44fa9b2010-03-02 13:46:51 -080016 ".gif": "image/gif",
Russ Cox91643ac2011-08-26 17:19:52 -040017 ".htm": "text/html; charset=utf-8",
18 ".html": "text/html; charset=utf-8",
Robert Griesemerf44fa9b2010-03-02 13:46:51 -080019 ".jpg": "image/jpeg",
20 ".js": "application/x-javascript",
21 ".pdf": "application/pdf",
22 ".png": "image/png",
Russ Cox91643ac2011-08-26 17:19:52 -040023 ".xml": "text/xml; charset=utf-8",
Michael Hoisie0cba5fc2010-02-09 20:47:45 -080024}
25
Yuusei Kuwanac21e2f32010-07-29 14:12:04 -070026var mimeLock sync.RWMutex
27
Rob Pikec78be462010-08-06 06:14:41 +100028var once sync.Once
29
Michael Hoisie0cba5fc2010-02-09 20:47:45 -080030// 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 "".
Brad Fitzpatrick9b64fef2010-07-14 17:26:14 -070033//
Alex Brainmanac17fd42011-11-18 10:07:36 +110034// The built-in table is small but on unix it is augmented by the local
Brad Fitzpatrick9b64fef2010-07-14 17:26:14 -070035// 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
Pascal S. de Kloebd3627c2011-08-26 16:55:25 -040041//
Alex Brainmanac17fd42011-11-18 10:07:36 +110042// Windows system mime types are extracted from registry.
43//
Pascal S. de Kloebd3627c2011-08-26 16:55:25 -040044// Text types have the charset parameter set to "utf-8" by default.
Michael Hoisie0cba5fc2010-02-09 20:47:45 -080045func TypeByExtension(ext string) string {
46 once.Do(initMime)
Yuusei Kuwanac21e2f32010-07-29 14:12:04 -070047 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".
Russ Coxc2049d22011-11-01 22:04:37 -040056func AddExtensionType(ext, typ string) error {
Pascal S. de Kloebd3627c2011-08-26 16:55:25 -040057 if ext == "" || ext[0] != '.' {
58 return fmt.Errorf(`mime: extension "%s" misses dot`, ext)
Yuusei Kuwanac21e2f32010-07-29 14:12:04 -070059 }
Pascal S. de Kloebd3627c2011-08-26 16:55:25 -040060 once.Do(initMime)
61 return setExtensionType(ext, typ)
62}
63
Russ Coxc2049d22011-11-01 22:04:37 -040064func setExtensionType(extension, mimeType string) error {
Brad Fitzpatricka00de452012-01-17 11:57:42 -080065 _, param, err := ParseMediaType(mimeType)
Pascal S. de Kloebd3627c2011-08-26 16:55:25 -040066 if err != nil {
67 return err
68 }
Brad Fitzpatricka00de452012-01-17 11:57:42 -080069 if strings.HasPrefix(mimeType, "text/") && param["charset"] == "" {
70 param["charset"] = "utf-8"
71 mimeType = FormatMediaType(mimeType, param)
Pascal S. de Kloebd3627c2011-08-26 16:55:25 -040072 }
Yuusei Kuwanac21e2f32010-07-29 14:12:04 -070073 mimeLock.Lock()
Pascal S. de Kloebd3627c2011-08-26 16:55:25 -040074 mimeTypes[extension] = mimeType
Yuusei Kuwanac21e2f32010-07-29 14:12:04 -070075 mimeLock.Unlock()
76 return nil
Michael Hoisie0cba5fc2010-02-09 20:47:45 -080077}