Skip to content

Commit

Permalink
MIME type detection
Browse files Browse the repository at this point in the history
mimetype module seems to work nicely and we can avoid a system dependency

Closes #4
  • Loading branch information
odrling committed Jul 15, 2024
1 parent 1c182bb commit 7f561a4
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 5 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (

require (
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.4 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/goccy/go-json v0.10.3 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s=
github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
Expand Down
21 changes: 19 additions & 2 deletions server/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"strings"

"github.com/danielgtaylor/huma/v2"
"github.com/gabriel-vasile/mimetype"
"github.com/google/uuid"
)

Expand Down Expand Up @@ -42,7 +43,15 @@ func Upload(ctx context.Context, input *UploadInput) (*UploadOutput, error) {
return nil, err
}

err = UploadToS3(ctx, fd, file_id.String(), file.Filename, file.Size)
det_buf := make([]byte, 1024)
n, err := fd.Read(det_buf)
if err != nil {
return nil, err
}
mime := mimetype.Detect(det_buf[:n])
fd.Seek(0, 0)

err = UploadToS3(ctx, fd, file_id.String(), file.Filename, file.Size, mime.String())
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -120,10 +129,18 @@ func Download(ctx context.Context, input *DownloadInput) (*huma.StreamResponse,

stat, err := obj.Stat()
filename := stat.UserMetadata["Filename"]
content_type := stat.UserMetadata["Type"]

main_type, _, _ := strings.Cut(content_type, "/")

ctx.SetHeader("Accept-Range", "bytes")
ctx.SetHeader("Content-Length", fmt.Sprintf("%d", stat.Size))
ctx.SetHeader("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
if main_type == "text" {
ctx.SetHeader("Content-Disposition", fmt.Sprintf("inline; filename=%s", filename))
} else {
ctx.SetHeader("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filename))
}
ctx.SetHeader("Content-Type", content_type)

var start int64
var end int64
Expand Down
13 changes: 12 additions & 1 deletion server/producer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"testing"

"github.com/danielgtaylor/huma/v2/humatest"
"github.com/gabriel-vasile/mimetype"
)

func getTestAPI(t *testing.T) humatest.TestAPI {
Expand Down Expand Up @@ -60,7 +61,8 @@ func uploadData(t *testing.T, api humatest.TestAPI, data []byte, filename string
func TestUploadDownload(t *testing.T) {
api := getTestAPI(t)

test_data := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9}
test_data := []byte("hello world")
mime := mimetype.Detect(test_data)
filename := "test_file"
upload_data := uploadData(t, api, test_data, filename)

Expand All @@ -83,6 +85,15 @@ func TestUploadDownload(t *testing.T) {

res := resp.Result()
content_disposition_header := res.Header["Content-Disposition"][0]
content_type := res.Header["Content-Type"][0]

if content_type == "" {
t.Fatal("Content-Type header is not set")
}

if content_type != mime.String() {
t.Fatalf("Content-Type header is not the detected file type: %s != %s", content_type, mime.String())
}

matched, _ := regexp.MatchString(
fmt.Sprintf("filename=%s", regexp.QuoteMeta(filename)),
Expand Down
7 changes: 5 additions & 2 deletions server/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func getS3Client() (*minio.Client, error) {
return client, err
}

func UploadToS3(ctx context.Context, file io.Reader, file_id string, filename string, filesize int64) error {
func UploadToS3(ctx context.Context, file io.Reader, file_id string, filename string, filesize int64, content_type string) error {
client, err := getS3Client()
if err != nil {
return err
Expand All @@ -31,7 +31,10 @@ func UploadToS3(ctx context.Context, file io.Reader, file_id string, filename st
file,
filesize,
minio.PutObjectOptions{
UserMetadata: map[string]string{"Filename": filename},
UserMetadata: map[string]string{
"Filename": filename,
"Type": content_type,
},
},
)
getLogger().Printf("upload info: %+v\n", info)
Expand Down

0 comments on commit 7f561a4

Please sign in to comment.