mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-03-11 17:48:44 -05:00
fix: detect and store mime type when creating file attachments
Use mimetype.DetectReader in files.Create to automatically detect and store the MIME type from file content. This fixes task attachment previews, S3 Content-Type headers, and UI display for newly uploaded files.
This commit is contained in:
@@ -37,6 +37,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/c2h5oh/datasize"
|
||||
"github.com/gabriel-vasile/mimetype"
|
||||
"github.com/spf13/afero"
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
@@ -86,7 +87,14 @@ func (f *File) LoadFileMetaByID() (err error) {
|
||||
|
||||
// Create creates a new file from an FileHeader
|
||||
func Create(f io.ReadSeeker, realname string, realsize uint64, a web.Auth) (file *File, err error) {
|
||||
return CreateWithMime(f, realname, realsize, a, "")
|
||||
mime, err := mimetype.DetectReader(f)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to detect mime type: %w", err)
|
||||
}
|
||||
if _, err := f.Seek(0, io.SeekStart); err != nil {
|
||||
return nil, fmt.Errorf("failed to seek after mime detection: %w", err)
|
||||
}
|
||||
return CreateWithMime(f, realname, realsize, a, mime.String())
|
||||
}
|
||||
|
||||
// CreateWithMime creates a new file from an FileHeader and sets its mime type
|
||||
|
||||
@@ -18,6 +18,8 @@ package files
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image"
|
||||
"image/png"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -60,6 +62,37 @@ func TestCreate(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestCreateDetectsMimeType(t *testing.T) {
|
||||
initFixtures(t)
|
||||
ta := &testauth{id: 1}
|
||||
|
||||
// Minimal valid PNG (1x1 pixel)
|
||||
pngData := createMinimalPNG(t)
|
||||
|
||||
f, err := Create(bytes.NewReader(pngData), "test.png", uint64(len(pngData)), ta)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "image/png", f.Mime)
|
||||
}
|
||||
|
||||
func TestCreateDetectsMimeTypePlainText(t *testing.T) {
|
||||
initFixtures(t)
|
||||
ta := &testauth{id: 1}
|
||||
|
||||
textData := []byte("hello world this is plain text")
|
||||
|
||||
f, err := Create(bytes.NewReader(textData), "readme.txt", uint64(len(textData)), ta)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "text/plain; charset=utf-8", f.Mime)
|
||||
}
|
||||
|
||||
func createMinimalPNG(t *testing.T) []byte {
|
||||
t.Helper()
|
||||
img := image.NewRGBA(image.Rect(0, 0, 1, 1))
|
||||
buf := &bytes.Buffer{}
|
||||
require.NoError(t, png.Encode(buf, img))
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func TestFile_Delete(t *testing.T) {
|
||||
t.Run("Normal", func(t *testing.T) {
|
||||
s := db.NewSession()
|
||||
|
||||
@@ -113,6 +113,7 @@ func TestTaskAttachment_NewAttachment(t *testing.T) {
|
||||
assert.Equal(t, testuser.ID, ta.File.CreatedByID)
|
||||
assert.Equal(t, "testfile", ta.File.Name)
|
||||
assert.Equal(t, uint64(100), ta.File.Size)
|
||||
assert.NotEmpty(t, ta.File.Mime, "mime type should be detected and stored")
|
||||
|
||||
// Extra test for max size test
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user