aboutsummaryrefslogtreecommitdiffstats
path: root/internal/web/filetype.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/web/filetype.go')
-rw-r--r--internal/web/filetype.go19
1 files changed, 13 insertions, 6 deletions
diff --git a/internal/web/filetype.go b/internal/web/filetype.go
index 9c0f590..60a220e 100644
--- a/internal/web/filetype.go
+++ b/internal/web/filetype.go
@@ -17,7 +17,8 @@ import (
// SVG or XML page must never render there. The rules below make that a
// property of the stored content type: the sniffer is trusted first, a
// filename extension may only refine a generic sniff to a type on an
-// allowlist, and anything not on the inline list is a download.
+// allowlist, and anything not on the inline list is a download. Fonts are
+// on it: a browser only ever parses one inside @font-face, never as a page.
// maxUploadFiles is how many files one Files-page request may carry; the body
// cap of that route is this many upload limits.
@@ -27,10 +28,10 @@ const maxUploadFiles = 10
// offsets, and the whole upload sits in memory while it is stored.
const maxUploadMB = 1024
-var fileKinds = []string{"image", "document", "audio", "video", "archive", "other"}
+var fileKinds = []string{"image", "document", "audio", "video", "font", "archive", "other"}
// fileKindNames are the tab labels (translated where used, like moduleNames).
-var fileKindNames = map[string]string{"image": "Images", "document": "Documents", "audio": "Audio", "video": "Video", "archive": "Archives", "other": "Other"}
+var fileKindNames = map[string]string{"image": "Images", "document": "Documents", "audio": "Audio", "video": "Video", "font": "Fonts", "archive": "Archives", "other": "Other"}
var imageTypes = map[string]bool{"image/png": true, "image/jpeg": true, "image/gif": true, "image/webp": true, "image/x-icon": true, "image/avif": true, "image/bmp": true}
@@ -50,6 +51,10 @@ var archiveTypes = map[string]bool{
"application/x-tar": true, "application/x-bzip2": true, "application/x-xz": true, "application/x-rar-compressed": true, "application/vnd.rar": true,
}
+// fontTypes are what the design page's font pickers take. Like images they
+// sniff exactly, so the name never refines into one; TTC and EOT stay "other".
+var fontTypes = map[string]bool{"font/woff2": true, "font/woff": true, "font/ttf": true, "font/otf": true}
+
var mediaTypes = map[string]bool{
"audio/mpeg": true, "audio/mp4": true, "audio/ogg": true, "audio/flac": true, "audio/wav": true, "audio/wave": true, "audio/x-wav": true, "audio/webm": true, "audio/aac": true,
"video/mp4": true, "video/ogg": true, "video/webm": true, "video/x-matroska": true, "video/quicktime": true,
@@ -91,8 +96,8 @@ func fileType(head []byte, filename string) (contentType, kind string) {
ct = "application/octet-stream"
}
}
- if !imageTypes[ct] && !extAllowed(ct) && !strings.HasPrefix(ct, "audio/") && !strings.HasPrefix(ct, "video/") {
- ct = "application/octet-stream" // sniffed HTML/XML, fonts, and everything else we do not name
+ if !imageTypes[ct] && !fontTypes[ct] && !extAllowed(ct) && !strings.HasPrefix(ct, "audio/") && !strings.HasPrefix(ct, "video/") {
+ ct = "application/octet-stream" // sniffed HTML/XML and everything else we do not name
}
return ct, kindOf(ct)
}
@@ -123,6 +128,8 @@ func kindOf(ct string) string {
return "audio"
case strings.HasPrefix(ct, "video/"):
return "video"
+ case fontTypes[ct]:
+ return "font"
case archiveTypes[ct]:
return "archive"
}
@@ -131,7 +138,7 @@ func kindOf(ct string) string {
// inlineOK says whether a browser may render the type in place.
func inlineOK(ct string) bool {
- return imageTypes[ct] || ct == "application/pdf" || ct == "text/plain" || strings.HasPrefix(ct, "audio/") || strings.HasPrefix(ct, "video/")
+ return imageTypes[ct] || fontTypes[ct] || ct == "application/pdf" || ct == "text/plain" || strings.HasPrefix(ct, "audio/") || strings.HasPrefix(ct, "video/")
}
// servedAs is the Content-Type and disposition /media answers with.