]> Cypherpunks repositories - gostls13.git/commitdiff
http: implement MP4 sniffing.
authorDavid Symonds <dsymonds@golang.org>
Tue, 26 Jul 2011 03:28:20 +0000 (13:28 +1000)
committerDavid Symonds <dsymonds@golang.org>
Tue, 26 Jul 2011 03:28:20 +0000 (13:28 +1000)
R=rsc
CC=golang-dev
https://golang.org/cl/4809044

src/pkg/http/sniff.go
src/pkg/http/sniff_test.go

index bf8ce2454508918ae44fc9948b67108f35ecc4a6..97b234e2813afc635642607e9bf4cc96c71ac005 100644 (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 {
index 2d01807f695aececb7136981df66449c3dd4f79c..baf3a418b53b5b1d85b9637530ff08629b24279a 100644 (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) {