From 4bdb8dd9cc028a071819afd8f79cf29b30ab4d30 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Tue, 15 Aug 2023 11:15:26 +0800 Subject: [PATCH] Detect ogg mime-type as audio or video (#26494) (#26505) Backport #26494 by @wxiaoguang "ogg" is just a "container" format for audio and video. Golang's `DetectContentType` only reports "application/ogg" for potential ogg files. Actually it could do more "guess" to see whether it is a audio file or a video file. Co-authored-by: wxiaoguang --- modules/typesniffer/typesniffer.go | 13 ++++++++++++- modules/typesniffer/typesniffer_test.go | 13 +++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/modules/typesniffer/typesniffer.go b/modules/typesniffer/typesniffer.go index 7887fd42b7..6aec5c285e 100644 --- a/modules/typesniffer/typesniffer.go +++ b/modules/typesniffer/typesniffer.go @@ -71,7 +71,7 @@ func (ct SniffedType) IsRepresentableAsText() bool { return ct.IsText() || ct.IsSvgImage() } -// IsBrowsableType returns whether a non-text type can be displayed in a browser +// IsBrowsableBinaryType returns whether a non-text type can be displayed in a browser func (ct SniffedType) IsBrowsableBinaryType() bool { return ct.IsImage() || ct.IsSvgImage() || ct.IsPDF() || ct.IsVideo() || ct.IsAudio() } @@ -116,6 +116,17 @@ func DetectContentType(data []byte) SniffedType { } } + if ct == "application/ogg" { + dataHead := data + if len(dataHead) > 256 { + dataHead = dataHead[:256] // only need to do a quick check for the file header + } + if bytes.Contains(dataHead, []byte("theora")) || bytes.Contains(dataHead, []byte("dirac")) { + ct = "video/ogg" // ogg is only used for some video formats, and it's not popular + } else { + ct = "audio/ogg" // for most cases, it is used as an audio container + } + } return SniffedType{ct} } diff --git a/modules/typesniffer/typesniffer_test.go b/modules/typesniffer/typesniffer_test.go index 6c6da34aa0..731fac11e7 100644 --- a/modules/typesniffer/typesniffer_test.go +++ b/modules/typesniffer/typesniffer_test.go @@ -6,6 +6,7 @@ package typesniffer import ( "bytes" "encoding/base64" + "encoding/hex" "strings" "testing" @@ -121,3 +122,15 @@ func TestDetectContentTypeFromReader(t *testing.T) { assert.NoError(t, err) assert.True(t, st.IsAudio()) } + +func TestDetectContentTypeOgg(t *testing.T) { + oggAudio, _ := hex.DecodeString("4f67675300020000000000000000352f0000000000007dc39163011e01766f72626973000000000244ac0000000000000071020000000000b8014f6767530000") + st, err := DetectContentTypeFromReader(bytes.NewReader(oggAudio)) + assert.NoError(t, err) + assert.True(t, st.IsAudio()) + + oggVideo, _ := hex.DecodeString("4f676753000200000000000000007d9747ef000000009b59daf3012a807468656f7261030201001e00110001e000010e00020000001e00000001000001000001") + st, err = DetectContentTypeFromReader(bytes.NewReader(oggVideo)) + assert.NoError(t, err) + assert.True(t, st.IsVideo()) +}