add load mp3

This commit is contained in:
2026-09-06 03:09:33 +07:00
parent 24f8b31fea
commit 106d2830fa
3 changed files with 12 additions and 0 deletions
+10
View File
@@ -96,6 +96,9 @@ func (s *FileService) UploadFile(
// Категория по содержимому (сырой sniff): text/* и octet-stream не
// проходят вообще, расширение должно соответствовать категории.
sniffed := http.DetectContentType(data)
if ext == ".mp3" && isMP3(data) {
sniffed = "audio/mpeg"
}
fileType := contentTypeCategory(sniffed)
if fileType == "" || fileType != file_storage.FileType(filename) {
return "", "", ErrInvalidContentType
@@ -117,6 +120,13 @@ func (s *FileService) UploadFile(
return storedName, fileType, nil
}
// isMP3 распознаёт MP3 без необязательного ID3-тега по заголовку MPEG-фрейма.
func isMP3(data []byte) bool {
return len(data) >= 4 && data[0] == 0xff && data[1]&0xe0 == 0xe0 &&
data[1]&0x18 != 0x08 && data[1]&0x06 != 0 &&
data[2]&0xf0 != 0 && data[2]&0xf0 != 0xf0 && data[2]&0x0c != 0x0c
}
// contentTypeCategory возвращает категорию по sniffed-типу:
// application/pdf → pdf; image/* → image; audio/* и application/ogg → audio;
// всё остальное (text/*, application/octet-stream и пр.) → "".
@@ -71,6 +71,7 @@ func TestUploadFileValid(t *testing.T) {
{"photo.PNG", []byte("\x89PNG\r\n\x1a\ncontent"), "image", ".png", "image/png"},
{"photo.jpg", []byte("\xff\xd8\xff\xe0jpeg-content"), "image", ".jpg", "image/jpeg"},
{"audio.mp3", []byte("ID3\x04\x00\x00\x00\x00\x00\x00audio"), "audio", ".mp3", "audio/mpeg"},
{"audio-no-id3.mp3", []byte("\xff\xfb\x90\x64audio"), "audio", ".mp3", "audio/mpeg"},
{"audio.ogg", []byte("OggS\x00\x02audio"), "audio", ".ogg", "application/ogg"},
{"audio.wav", []byte("RIFF\x24\x00\x00\x00WAVEfmt "), "audio", ".wav", "audio/wave"},
}
@@ -126,6 +127,7 @@ func TestUploadFileValidation(t *testing.T) {
{"base из не-латиницы (!!!.pdf)", "!!!.pdf", pdf, ErrEmptyName},
{"html под видом png", "photo.png", []byte("<html>hi</html>"), ErrInvalidContentType},
{"octet-stream", "clue.pdf", []byte{0x00, 0x01, 0x02, 0x03}, ErrInvalidContentType},
{"ложный mp3 sync", "audio.mp3", []byte{0xff, 0xe0, 0x00, 0x00}, ErrInvalidContentType},
{"mismatch pdf+png", "clue.pdf", []byte("\x89PNG\r\n\x1a\ncontent"), ErrInvalidContentType},
}
for _, c := range cases {