http: implement MP4 sniffing.

R=rsc
CC=golang-dev
https://golang.org/cl/4809044
This commit is contained in:
David Symonds 2011-07-26 13:28:20 +10:00
parent 003d5411ae
commit e527d49e55
2 changed files with 30 additions and 1 deletions

View File

@ -6,6 +6,7 @@ package http
import (
"bytes"
"encoding/binary"
)
// Content-type sniffing algorithm.
@ -97,7 +98,7 @@ var sniffSignatures = []sniffSig{
&exactSig{[]byte("\x50\x4B\x03\x04"), "application/zip"},
&exactSig{[]byte("\x1F\x8B\x08"), "application/x-gzip"},
// TODO(dsymonds): MP4.
mp4Sig(0),
textSig(0), // should be last
}
@ -159,6 +160,32 @@ func (h htmlSig) match(data []byte, firstNonWS int) string {
return "text/html; charset=utf-8"
}
type mp4Sig int
func (mp4Sig) match(data []byte, firstNonWS int) string {
// c.f. section 6.1.
if len(data) < 8 {
return ""
}
boxSize := int(binary.BigEndian.Uint32(data[:4]))
if boxSize%4 != 0 || len(data) < boxSize {
return ""
}
if !bytes.Equal(data[4:8], []byte("ftyp")) {
return ""
}
for st := 8; st < boxSize; st += 4 {
if st == 12 {
// minor version number
continue
}
if bytes.Equal(data[st:st+3], []byte("mp4")) {
return "video/mp4"
}
}
return ""
}
type textSig int
func (textSig) match(data []byte, firstNonWS int) string {

View File

@ -34,6 +34,8 @@ var sniffTests = []struct {
// Image types.
{"GIF 87a", []byte(`GIF87a`), "image/gif"},
{"GIF 89a", []byte(`GIF89a...`), "image/gif"},
{"MP4", []byte("\x00\x00\x00\x18ftypmp42\x00\x00\x00\x00mp42isom<\x06t\xbfmdat"), "video/mp4"},
}
func TestDetectContentType(t *testing.T) {