1
0
mirror of https://github.com/golang/go synced 2024-11-26 02:17:58 -07:00

mime: new package, use in http

R=rsc
CC=golang-dev
https://golang.org/cl/186160
This commit is contained in:
Michael Hoisie 2010-02-09 20:47:45 -08:00 committed by Russ Cox
parent 766d042e48
commit 0cba5fc051
6 changed files with 132 additions and 12 deletions

View File

@ -87,6 +87,7 @@ DIRS=\
json\ json\
log\ log\
math\ math\
mime\
net\ net\
once\ once\
os\ os\

View File

@ -9,23 +9,13 @@ package http
import ( import (
"fmt" "fmt"
"io" "io"
"mime"
"os" "os"
"path" "path"
"strings" "strings"
"utf8" "utf8"
) )
// TODO this should be in a mime package somewhere
var contentByExt = map[string]string{
".css": "text/css",
".gif": "image/gif",
".html": "text/html; charset=utf-8",
".jpg": "image/jpeg",
".js": "application/x-javascript",
".pdf": "application/pdf",
".png": "image/png",
}
// Heuristic: b is text if it is valid UTF-8 and doesn't // Heuristic: b is text if it is valid UTF-8 and doesn't
// contain any unprintable ASCII or Unicode characters. // contain any unprintable ASCII or Unicode characters.
func isText(b []byte) bool { func isText(b []byte) bool {
@ -136,7 +126,7 @@ func serveFileInternal(c *Conn, r *Request, name string, redirect bool) {
// serve file // serve file
// use extension to find content type. // use extension to find content type.
ext := path.Ext(name) ext := path.Ext(name)
if ctype, ok := contentByExt[ext]; ok { if ctype := mime.TypeByExtension(ext); ctype != "" {
c.SetHeader("Content-Type", ctype) c.SetHeader("Content-Type", ctype)
} else { } else {
// read first chunk to decide between utf-8 text and binary // read first chunk to decide between utf-8 text and binary

11
src/pkg/mime/Makefile Normal file
View File

@ -0,0 +1,11 @@
# Copyright 2009 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.
include ../../Make.$(GOARCH)
TARG=mime
GOFILES=\
type.go\
include ../../Make.pkg

27
src/pkg/mime/mime_test.go Normal file
View File

@ -0,0 +1,27 @@
// Copyright 2010 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.
// Tests for type.go
package mime
import "testing"
var typeTests = map[string]string{
".t1": "application/test",
".t2": "text/test; charset=utf-8",
".png": "image/png",
}
func TestType(t *testing.T) {
typeFiles = []string{"test.types"}
for ext, want := range typeTests {
val := TypeByExtension(ext)
if val != want {
t.Errorf("TypeByExtension(%q) = %q, want %q", ext, val, want)
}
}
}

8
src/pkg/mime/test.types Normal file
View File

@ -0,0 +1,8 @@
# Copyright 2010 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
application/test t1 # Simple test
text/test t2 # Text test

83
src/pkg/mime/type.go Normal file
View File

@ -0,0 +1,83 @@
// Copyright 2010 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.
// The mime package translates file name extensions to MIME types.
// It consults the local system's mime.types file, which must be installed
// under one of these names:
//
// /etc/mime.types
// /etc/apache2/mime.types
// /etc/apache/mime.types
//
package mime
import (
"bufio"
"once"
"os"
"strings"
)
var typeFiles = []string{
"/etc/mime.types",
"/etc/apache2/mime.types",
"/etc/apache/mime.types",
}
var mimeTypes = map[string]string{
".css": "text/css",
".gif": "image/gif",
".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",
}
func loadMimeFile(filename string) {
f, err := os.Open(filename, os.O_RDONLY, 0666)
if err != nil {
return
}
reader := bufio.NewReader(f)
for {
line, err := reader.ReadString('\n')
if err != nil {
f.Close()
return
}
fields := strings.Fields(line)
if len(fields) <= 1 || fields[0][0] == '#' {
continue
}
typename := fields[0]
if strings.HasPrefix(typename, "text/") {
typename += "; charset=utf-8"
}
for _, ext := range fields[1:] {
if ext[0] == '#' {
break
}
mimeTypes["."+ext] = typename
}
}
}
func initMime() {
for _, filename := range typeFiles {
loadMimeFile(filename)
}
}
// TypeByExtension returns the MIME type associated with the file extension ext.
// The extension ext should begin with a leading dot, as in ".html".
// When ext has no associated type, TypeByExtension returns "".
func TypeByExtension(ext string) string {
once.Do(initMime)
typ, _ := mimeTypes[ext]
return typ
}