diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/avatar/avatar.go | 5 | ||||
-rw-r--r-- | modules/base/tool.go | 68 | ||||
-rw-r--r-- | modules/base/tool_test.go | 92 | ||||
-rw-r--r-- | modules/git/blob.go | 13 | ||||
-rw-r--r-- | modules/git/commit.go | 70 | ||||
-rw-r--r-- | modules/indexer/code/bleve.go | 4 | ||||
-rw-r--r-- | modules/indexer/code/elastic_search.go | 4 | ||||
-rw-r--r-- | modules/typesniffer/typesniffer.go | 96 | ||||
-rw-r--r-- | modules/typesniffer/typesniffer_test.go | 97 |
9 files changed, 213 insertions, 236 deletions
diff --git a/modules/avatar/avatar.go b/modules/avatar/avatar.go index bb9c2e953b..5411a90796 100644 --- a/modules/avatar/avatar.go +++ b/modules/avatar/avatar.go @@ -10,8 +10,9 @@ import ( "image" "image/color/palette" - // Enable PNG support: - _ "image/png" + _ "image/gif" // for processing gif images + _ "image/jpeg" // for processing jpeg images + _ "image/png" // for processing png images "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" diff --git a/modules/base/tool.go b/modules/base/tool.go index c9530473e2..775fd709cf 100644 --- a/modules/base/tool.go +++ b/modules/base/tool.go @@ -12,10 +12,8 @@ import ( "encoding/hex" "errors" "fmt" - "net/http" "os" "path/filepath" - "regexp" "runtime" "strconv" "strings" @@ -30,15 +28,6 @@ import ( "github.com/dustin/go-humanize" ) -// Use at most this many bytes to determine Content Type. -const sniffLen = 512 - -// SVGMimeType MIME type of SVG images. -const SVGMimeType = "image/svg+xml" - -var svgTagRegex = regexp.MustCompile(`(?si)\A\s*(?:(<!--.*?-->|<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg[\s>\/]`) -var svgTagInXMLRegex = regexp.MustCompile(`(?si)\A<\?xml\b.*?\?>\s*(?:(<!--.*?-->|<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg[\s>\/]`) - // EncodeMD5 encodes string to md5 hex value. func EncodeMD5(str string) string { m := md5.New() @@ -276,63 +265,6 @@ func IsLetter(ch rune) bool { return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch) } -// DetectContentType extends http.DetectContentType with more content types. -func DetectContentType(data []byte) string { - ct := http.DetectContentType(data) - - if len(data) > sniffLen { - data = data[:sniffLen] - } - - if setting.UI.SVG.Enabled && - ((strings.Contains(ct, "text/plain") || strings.Contains(ct, "text/html")) && svgTagRegex.Match(data) || - strings.Contains(ct, "text/xml") && svgTagInXMLRegex.Match(data)) { - - // SVG is unsupported. https://github.com/golang/go/issues/15888 - return SVGMimeType - } - return ct -} - -// IsRepresentableAsText returns true if file content can be represented as -// plain text or is empty. -func IsRepresentableAsText(data []byte) bool { - return IsTextFile(data) || IsSVGImageFile(data) -} - -// IsTextFile returns true if file content format is plain text or empty. -func IsTextFile(data []byte) bool { - if len(data) == 0 { - return true - } - return strings.Contains(DetectContentType(data), "text/") -} - -// IsImageFile detects if data is an image format -func IsImageFile(data []byte) bool { - return strings.Contains(DetectContentType(data), "image/") -} - -// IsSVGImageFile detects if data is an SVG image format -func IsSVGImageFile(data []byte) bool { - return strings.Contains(DetectContentType(data), SVGMimeType) -} - -// IsPDFFile detects if data is a pdf format -func IsPDFFile(data []byte) bool { - return strings.Contains(DetectContentType(data), "application/pdf") -} - -// IsVideoFile detects if data is an video format -func IsVideoFile(data []byte) bool { - return strings.Contains(DetectContentType(data), "video/") -} - -// IsAudioFile detects if data is an video format -func IsAudioFile(data []byte) bool { - return strings.Contains(DetectContentType(data), "audio/") -} - // EntryIcon returns the octicon class for displaying files/directories func EntryIcon(entry *git.TreeEntry) string { switch { diff --git a/modules/base/tool_test.go b/modules/base/tool_test.go index fcd3ca296a..1343f5bed3 100644 --- a/modules/base/tool_test.go +++ b/modules/base/tool_test.go @@ -5,7 +5,6 @@ package base import ( - "encoding/base64" "os" "testing" "time" @@ -246,97 +245,6 @@ func TestIsLetter(t *testing.T) { assert.False(t, IsLetter(0x93)) } -func TestDetectContentTypeLongerThanSniffLen(t *testing.T) { - // Pre-condition: Shorter than sniffLen detects SVG. - assert.Equal(t, "image/svg+xml", DetectContentType([]byte(`<!-- Comment --><svg></svg>`))) - // Longer than sniffLen detects something else. - assert.Equal(t, "text/plain; charset=utf-8", DetectContentType([]byte(`<!-- -Comment Comment Comment Comment Comment Comment Comment Comment Comment Comment -Comment Comment Comment Comment Comment Comment Comment Comment Comment Comment -Comment Comment Comment Comment Comment Comment Comment Comment Comment Comment -Comment Comment Comment Comment Comment Comment Comment Comment Comment Comment -Comment Comment Comment Comment Comment Comment Comment Comment Comment Comment -Comment Comment Comment Comment Comment Comment Comment Comment Comment Comment -Comment Comment Comment --><svg></svg>`))) -} - -// IsRepresentableAsText - -func TestIsTextFile(t *testing.T) { - assert.True(t, IsTextFile([]byte{})) - assert.True(t, IsTextFile([]byte("lorem ipsum"))) -} - -func TestIsImageFile(t *testing.T) { - png, _ := base64.StdEncoding.DecodeString("iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAG0lEQVQYlWN4+vTpf3SMDTAMBYXYBLFpHgoKAeiOf0SGE9kbAAAAAElFTkSuQmCC") - assert.True(t, IsImageFile(png)) - assert.False(t, IsImageFile([]byte("plain text"))) -} - -func TestIsSVGImageFile(t *testing.T) { - assert.True(t, IsSVGImageFile([]byte("<svg></svg>"))) - assert.True(t, IsSVGImageFile([]byte(" <svg></svg>"))) - assert.True(t, IsSVGImageFile([]byte(`<svg width="100"></svg>`))) - assert.True(t, IsSVGImageFile([]byte("<svg/>"))) - assert.True(t, IsSVGImageFile([]byte(`<?xml version="1.0" encoding="UTF-8"?><svg></svg>`))) - assert.True(t, IsSVGImageFile([]byte(`<!-- Comment --> - <svg></svg>`))) - assert.True(t, IsSVGImageFile([]byte(`<!-- Multiple --> - <!-- Comments --> - <svg></svg>`))) - assert.True(t, IsSVGImageFile([]byte(`<!-- Multiline - Comment --> - <svg></svg>`))) - assert.True(t, IsSVGImageFile([]byte(`<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" - "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd"> - <svg></svg>`))) - assert.True(t, IsSVGImageFile([]byte(`<?xml version="1.0" encoding="UTF-8"?> - <!-- Comment --> - <svg></svg>`))) - assert.True(t, IsSVGImageFile([]byte(`<?xml version="1.0" encoding="UTF-8"?> - <!-- Multiple --> - <!-- Comments --> - <svg></svg>`))) - assert.True(t, IsSVGImageFile([]byte(`<?xml version="1.0" encoding="UTF-8"?> - <!-- Multline - Comment --> - <svg></svg>`))) - assert.True(t, IsSVGImageFile([]byte(`<?xml version="1.0" encoding="UTF-8"?> - <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> - <!-- Multline - Comment --> - <svg></svg>`))) - assert.False(t, IsSVGImageFile([]byte{})) - assert.False(t, IsSVGImageFile([]byte("svg"))) - assert.False(t, IsSVGImageFile([]byte("<svgfoo></svgfoo>"))) - assert.False(t, IsSVGImageFile([]byte("text<svg></svg>"))) - assert.False(t, IsSVGImageFile([]byte("<html><body><svg></svg></body></html>"))) - assert.False(t, IsSVGImageFile([]byte(`<script>"<svg></svg>"</script>`))) - assert.False(t, IsSVGImageFile([]byte(`<!-- <svg></svg> inside comment --> - <foo></foo>`))) - assert.False(t, IsSVGImageFile([]byte(`<?xml version="1.0" encoding="UTF-8"?> - <!-- <svg></svg> inside comment --> - <foo></foo>`))) -} - -func TestIsPDFFile(t *testing.T) { - pdf, _ := base64.StdEncoding.DecodeString("JVBERi0xLjYKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nF3NPwsCMQwF8D2f4s2CNYk1baF0EHRwOwg4iJt/NsFb/PpevUE4Mjwe") - assert.True(t, IsPDFFile(pdf)) - assert.False(t, IsPDFFile([]byte("plain text"))) -} - -func TestIsVideoFile(t *testing.T) { - mp4, _ := base64.StdEncoding.DecodeString("AAAAGGZ0eXBtcDQyAAAAAGlzb21tcDQyAAEI721vb3YAAABsbXZoZAAAAADaBlwX2gZcFwAAA+gA") - assert.True(t, IsVideoFile(mp4)) - assert.False(t, IsVideoFile([]byte("plain text"))) -} - -func TestIsAudioFile(t *testing.T) { - mp3, _ := base64.StdEncoding.DecodeString("SUQzBAAAAAABAFRYWFgAAAASAAADbWFqb3JfYnJhbmQAbXA0MgBUWFhYAAAAEQAAA21pbm9yX3Zl") - assert.True(t, IsAudioFile(mp3)) - assert.False(t, IsAudioFile([]byte("plain text"))) -} - // TODO: Test EntryIcon func TestSetupGiteaRoot(t *testing.T) { diff --git a/modules/git/blob.go b/modules/git/blob.go index 674a6a9592..732356e5b2 100644 --- a/modules/git/blob.go +++ b/modules/git/blob.go @@ -10,6 +10,8 @@ import ( "encoding/base64" "io" "io/ioutil" + + "code.gitea.io/gitea/modules/typesniffer" ) // This file contains common functions between the gogit and !gogit variants for git Blobs @@ -82,3 +84,14 @@ func (b *Blob) GetBlobContentBase64() (string, error) { } return string(out), nil } + +// GuessContentType guesses the content type of the blob. +func (b *Blob) GuessContentType() (typesniffer.SniffedType, error) { + r, err := b.DataAsync() + if err != nil { + return typesniffer.SniffedType{}, err + } + defer r.Close() + + return typesniffer.DetectContentTypeFromReader(r) +} diff --git a/modules/git/commit.go b/modules/git/commit.go index 027642720d..f4d6075fe2 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -11,13 +11,7 @@ import ( "container/list" "errors" "fmt" - "image" - "image/color" - _ "image/gif" // for processing gif images - _ "image/jpeg" // for processing jpeg images - _ "image/png" // for processing png images "io" - "net/http" "os/exec" "strconv" "strings" @@ -81,70 +75,6 @@ func (c *Commit) ParentCount() int { return len(c.Parents) } -func isImageFile(data []byte) (string, bool) { - contentType := http.DetectContentType(data) - if strings.Contains(contentType, "image/") { - return contentType, true - } - return contentType, false -} - -// IsImageFile is a file image type -func (c *Commit) IsImageFile(name string) bool { - blob, err := c.GetBlobByPath(name) - if err != nil { - return false - } - - dataRc, err := blob.DataAsync() - if err != nil { - return false - } - defer dataRc.Close() - buf := make([]byte, 1024) - n, _ := dataRc.Read(buf) - buf = buf[:n] - _, isImage := isImageFile(buf) - return isImage -} - -// ImageMetaData represents metadata of an image file -type ImageMetaData struct { - ColorModel color.Model - Width int - Height int - ByteSize int64 -} - -// ImageInfo returns information about the dimensions of an image -func (c *Commit) ImageInfo(name string) (*ImageMetaData, error) { - if !c.IsImageFile(name) { - return nil, nil - } - - blob, err := c.GetBlobByPath(name) - if err != nil { - return nil, err - } - reader, err := blob.DataAsync() - if err != nil { - return nil, err - } - defer reader.Close() - config, _, err := image.DecodeConfig(reader) - if err != nil { - return nil, err - } - - metadata := ImageMetaData{ - ColorModel: config.ColorModel, - Width: config.Width, - Height: config.Height, - ByteSize: blob.Size(), - } - return &metadata, nil -} - // GetCommitByPath return the commit of relative path object. func (c *Commit) GetCommitByPath(relpath string) (*Commit, error) { return c.repo.getCommitByPathWithID(c.ID, relpath) diff --git a/modules/indexer/code/bleve.go b/modules/indexer/code/bleve.go index 1d6aa51bc2..17128052f4 100644 --- a/modules/indexer/code/bleve.go +++ b/modules/indexer/code/bleve.go @@ -16,12 +16,12 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/analyze" - "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/typesniffer" "code.gitea.io/gitea/modules/util" "github.com/blevesearch/bleve/v2" @@ -211,7 +211,7 @@ func (b *BleveIndexer) addUpdate(batchWriter git.WriteCloserError, batchReader * fileContents, err := ioutil.ReadAll(io.LimitReader(batchReader, size)) if err != nil { return err - } else if !base.IsTextFile(fileContents) { + } else if !typesniffer.DetectContentType(fileContents).IsText() { // FIXME: UTF-16 files will probably fail here return nil } diff --git a/modules/indexer/code/elastic_search.go b/modules/indexer/code/elastic_search.go index 982b36e8df..16d4a1821a 100644 --- a/modules/indexer/code/elastic_search.go +++ b/modules/indexer/code/elastic_search.go @@ -16,12 +16,12 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/analyze" - "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/typesniffer" "github.com/go-enry/go-enry/v2" jsoniter "github.com/json-iterator/go" @@ -210,7 +210,7 @@ func (b *ElasticSearchIndexer) addUpdate(batchWriter git.WriteCloserError, batch fileContents, err := ioutil.ReadAll(io.LimitReader(batchReader, size)) if err != nil { return nil, err - } else if !base.IsTextFile(fileContents) { + } else if !typesniffer.DetectContentType(fileContents).IsText() { // FIXME: UTF-16 files will probably fail here return nil, nil } diff --git a/modules/typesniffer/typesniffer.go b/modules/typesniffer/typesniffer.go new file mode 100644 index 0000000000..7c89f66699 --- /dev/null +++ b/modules/typesniffer/typesniffer.go @@ -0,0 +1,96 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package typesniffer + +import ( + "fmt" + "io" + "net/http" + "regexp" + "strings" +) + +// Use at most this many bytes to determine Content Type. +const sniffLen = 1024 + +// SvgMimeType MIME type of SVG images. +const SvgMimeType = "image/svg+xml" + +var svgTagRegex = regexp.MustCompile(`(?si)\A\s*(?:(<!--.*?-->|<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg[\s>\/]`) +var svgTagInXMLRegex = regexp.MustCompile(`(?si)\A<\?xml\b.*?\?>\s*(?:(<!--.*?-->|<!DOCTYPE\s+svg([\s:]+.*?>|>))\s*)*<svg[\s>\/]`) + +// SniffedType contains informations about a blobs type. +type SniffedType struct { + contentType string +} + +// IsText etects if content format is plain text. +func (ct SniffedType) IsText() bool { + return strings.Contains(ct.contentType, "text/") +} + +// IsImage detects if data is an image format +func (ct SniffedType) IsImage() bool { + return strings.Contains(ct.contentType, "image/") +} + +// IsSvgImage detects if data is an SVG image format +func (ct SniffedType) IsSvgImage() bool { + return strings.Contains(ct.contentType, SvgMimeType) +} + +// IsPDF detects if data is a PDF format +func (ct SniffedType) IsPDF() bool { + return strings.Contains(ct.contentType, "application/pdf") +} + +// IsVideo detects if data is an video format +func (ct SniffedType) IsVideo() bool { + return strings.Contains(ct.contentType, "video/") +} + +// IsAudio detects if data is an video format +func (ct SniffedType) IsAudio() bool { + return strings.Contains(ct.contentType, "audio/") +} + +// IsRepresentableAsText returns true if file content can be represented as +// plain text or is empty. +func (ct SniffedType) IsRepresentableAsText() bool { + return ct.IsText() || ct.IsSvgImage() +} + +// DetectContentType extends http.DetectContentType with more content types. Defaults to text/unknown if input is empty. +func DetectContentType(data []byte) SniffedType { + if len(data) == 0 { + return SniffedType{"text/unknown"} + } + + ct := http.DetectContentType(data) + + if len(data) > sniffLen { + data = data[:sniffLen] + } + + if (strings.Contains(ct, "text/plain") || strings.Contains(ct, "text/html")) && svgTagRegex.Match(data) || + strings.Contains(ct, "text/xml") && svgTagInXMLRegex.Match(data) { + // SVG is unsupported. https://github.com/golang/go/issues/15888 + ct = SvgMimeType + } + + return SniffedType{ct} +} + +// DetectContentTypeFromReader guesses the content type contained in the reader. +func DetectContentTypeFromReader(r io.Reader) (SniffedType, error) { + buf := make([]byte, sniffLen) + n, err := r.Read(buf) + if err != nil && err != io.EOF { + return SniffedType{}, fmt.Errorf("DetectContentTypeFromReader io error: %w", err) + } + buf = buf[:n] + + return DetectContentType(buf), nil +} diff --git a/modules/typesniffer/typesniffer_test.go b/modules/typesniffer/typesniffer_test.go new file mode 100644 index 0000000000..a3b47c4598 --- /dev/null +++ b/modules/typesniffer/typesniffer_test.go @@ -0,0 +1,97 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package typesniffer + +import ( + "bytes" + "encoding/base64" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDetectContentTypeLongerThanSniffLen(t *testing.T) { + // Pre-condition: Shorter than sniffLen detects SVG. + assert.Equal(t, "image/svg+xml", DetectContentType([]byte(`<!-- Comment --><svg></svg>`)).contentType) + // Longer than sniffLen detects something else. + assert.NotEqual(t, "image/svg+xml", DetectContentType([]byte(`<!-- `+strings.Repeat("x", sniffLen)+` --><svg></svg>`)).contentType) +} + +func TestIsTextFile(t *testing.T) { + assert.True(t, DetectContentType([]byte{}).IsText()) + assert.True(t, DetectContentType([]byte("lorem ipsum")).IsText()) +} + +func TestIsSvgImage(t *testing.T) { + assert.True(t, DetectContentType([]byte("<svg></svg>")).IsSvgImage()) + assert.True(t, DetectContentType([]byte(" <svg></svg>")).IsSvgImage()) + assert.True(t, DetectContentType([]byte(`<svg width="100"></svg>`)).IsSvgImage()) + assert.True(t, DetectContentType([]byte("<svg/>")).IsSvgImage()) + assert.True(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?><svg></svg>`)).IsSvgImage()) + assert.True(t, DetectContentType([]byte(`<!-- Comment --> + <svg></svg>`)).IsSvgImage()) + assert.True(t, DetectContentType([]byte(`<!-- Multiple --> + <!-- Comments --> + <svg></svg>`)).IsSvgImage()) + assert.True(t, DetectContentType([]byte(`<!-- Multiline + Comment --> + <svg></svg>`)).IsSvgImage()) + assert.True(t, DetectContentType([]byte(`<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Basic//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-basic.dtd"> + <svg></svg>`)).IsSvgImage()) + assert.True(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?> + <!-- Comment --> + <svg></svg>`)).IsSvgImage()) + assert.True(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?> + <!-- Multiple --> + <!-- Comments --> + <svg></svg>`)).IsSvgImage()) + assert.True(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?> + <!-- Multline + Comment --> + <svg></svg>`)).IsSvgImage()) + assert.True(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> + <!-- Multline + Comment --> + <svg></svg>`)).IsSvgImage()) + assert.False(t, DetectContentType([]byte{}).IsSvgImage()) + assert.False(t, DetectContentType([]byte("svg")).IsSvgImage()) + assert.False(t, DetectContentType([]byte("<svgfoo></svgfoo>")).IsSvgImage()) + assert.False(t, DetectContentType([]byte("text<svg></svg>")).IsSvgImage()) + assert.False(t, DetectContentType([]byte("<html><body><svg></svg></body></html>")).IsSvgImage()) + assert.False(t, DetectContentType([]byte(`<script>"<svg></svg>"</script>`)).IsSvgImage()) + assert.False(t, DetectContentType([]byte(`<!-- <svg></svg> inside comment --> + <foo></foo>`)).IsSvgImage()) + assert.False(t, DetectContentType([]byte(`<?xml version="1.0" encoding="UTF-8"?> + <!-- <svg></svg> inside comment --> + <foo></foo>`)).IsSvgImage()) +} + +func TestIsPDF(t *testing.T) { + pdf, _ := base64.StdEncoding.DecodeString("JVBERi0xLjYKJcOkw7zDtsOfCjIgMCBvYmoKPDwvTGVuZ3RoIDMgMCBSL0ZpbHRlci9GbGF0ZURlY29kZT4+CnN0cmVhbQp4nF3NPwsCMQwF8D2f4s2CNYk1baF0EHRwOwg4iJt/NsFb/PpevUE4Mjwe") + assert.True(t, DetectContentType(pdf).IsPDF()) + assert.False(t, DetectContentType([]byte("plain text")).IsPDF()) +} + +func TestIsVideo(t *testing.T) { + mp4, _ := base64.StdEncoding.DecodeString("AAAAGGZ0eXBtcDQyAAAAAGlzb21tcDQyAAEI721vb3YAAABsbXZoZAAAAADaBlwX2gZcFwAAA+gA") + assert.True(t, DetectContentType(mp4).IsVideo()) + assert.False(t, DetectContentType([]byte("plain text")).IsVideo()) +} + +func TestIsAudio(t *testing.T) { + mp3, _ := base64.StdEncoding.DecodeString("SUQzBAAAAAABAFRYWFgAAAASAAADbWFqb3JfYnJhbmQAbXA0MgBUWFhYAAAAEQAAA21pbm9yX3Zl") + assert.True(t, DetectContentType(mp3).IsAudio()) + assert.False(t, DetectContentType([]byte("plain text")).IsAudio()) +} + +func TestDetectContentTypeFromReader(t *testing.T) { + mp3, _ := base64.StdEncoding.DecodeString("SUQzBAAAAAABAFRYWFgAAAASAAADbWFqb3JfYnJhbmQAbXA0MgBUWFhYAAAAEQAAA21pbm9yX3Zl") + st, err := DetectContentTypeFromReader(bytes.NewReader(mp3)) + assert.NoError(t, err) + assert.True(t, st.IsAudio()) +} |