forked from NdoleStudio/httpsms
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathattachment_repository.go
More file actions
99 lines (89 loc) · 2.91 KB
/
Copy pathattachment_repository.go
File metadata and controls
99 lines (89 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package repositories
import (
"context"
"fmt"
"path/filepath"
"strings"
)
// AttachmentRepository is the interface for storing and retrieving message attachments
type AttachmentRepository interface {
// Upload stores attachment data at the given path with the specified content type
Upload(ctx context.Context, path string, data []byte, contentType string) error
// Download retrieves attachment data from the given path
Download(ctx context.Context, path string) ([]byte, error)
// Delete removes an attachment at the given path
Delete(ctx context.Context, path string) error
}
// contentTypeExtensions maps MIME types to file extensions
var contentTypeExtensions = map[string]string{
"image/jpeg": ".jpg",
"image/png": ".png",
"image/gif": ".gif",
"image/webp": ".webp",
"image/bmp": ".bmp",
"video/mp4": ".mp4",
"video/3gpp": ".3gp",
"audio/mpeg": ".mp3",
"audio/ogg": ".ogg",
"audio/amr": ".amr",
"application/pdf": ".pdf",
"text/vcard": ".vcf",
"text/x-vcard": ".vcf",
}
// extensionContentTypes is the reverse map from file extensions to canonical MIME types
var extensionContentTypes = map[string]string{
".jpg": "image/jpeg",
".png": "image/png",
".gif": "image/gif",
".webp": "image/webp",
".bmp": "image/bmp",
".mp4": "video/mp4",
".3gp": "video/3gpp",
".mp3": "audio/mpeg",
".ogg": "audio/ogg",
".amr": "audio/amr",
".pdf": "application/pdf",
".vcf": "text/vcard",
}
// AllowedContentTypes returns the set of allowed MIME types for attachments
func AllowedContentTypes() map[string]bool {
allowed := make(map[string]bool, len(contentTypeExtensions))
for ct := range contentTypeExtensions {
allowed[ct] = true
}
return allowed
}
// ExtensionFromContentType returns the file extension for a MIME content type.
// Returns ".bin" if the content type is not recognized.
func ExtensionFromContentType(contentType string) string {
if ext, ok := contentTypeExtensions[contentType]; ok {
return ext
}
return ".bin"
}
// ContentTypeFromExtension returns the MIME content type for a file extension.
// Returns "application/octet-stream" if the extension is not recognized.
func ContentTypeFromExtension(ext string) string {
if ct, ok := extensionContentTypes[ext]; ok {
return ct
}
return "application/octet-stream"
}
// SanitizeFilename removes path separators and traversal sequences from a filename.
// Returns "attachment-{index}" if the sanitized name is empty.
func SanitizeFilename(name string, index int) string {
name = strings.TrimSuffix(name, filepath.Ext(name))
var builder strings.Builder
for _, r := range name {
if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '_' || r == '-' {
builder.WriteRune(r)
} else if r == ' ' {
builder.WriteRune('-')
}
}
name = strings.Trim(builder.String(), "-")
if name == "" {
return fmt.Sprintf("attachment-%d", index)
}
return name
}