Files
summercms/modules/lagoon/attach/inline.go
Jakub Zych ba8432cfb8 fix(lagoon/attach): store non-inline uploads with Content-Disposition attachment (quick-261028-rqe)
- attach.IsInlineContentType: the shared inline raster list (JPEG, PNG,
  GIF, WebP, AVIF), parameters and case ignored, false for empty or
  unparsable values
- writeBlob stores Content-Disposition: attachment for every other type,
  so a public bucket or CDN makes the browser download HTML, SVG, PDF or
  plain text; content_type and thumbnails are unchanged
- driver tests on memblob and fileblob, Postgres-backed Store assertion,
  lagoon README and the storage and attachments pages
2026-10-28 21:10:48 +01:00

45 lines
1.5 KiB
Go

package attach
import (
"mime"
"strings"
"gocloud.dev/blob"
)
// inlineContentTypes are the raster image types a browser may show inline
// from an upload.
var inlineContentTypes = map[string]bool{
"image/avif": true,
"image/gif": true,
"image/jpeg": true,
"image/png": true,
"image/webp": true,
}
// attachmentDisposition is the Content-Disposition stored with a non-inline
// upload. It is the bare value with no filename parameter: the client's file
// name never reaches blob metadata or a response header.
const attachmentDisposition = "attachment"
// IsInlineContentType reports whether contentType, with parameters and case
// ignored, is a raster image a browser may show inline from an upload (JPEG,
// PNG, GIF, WebP, AVIF). An empty or unparsable value is not. Store stores
// every other type, SVG, PDF, HTML and plain text included, with
// Content-Disposition: attachment, and the surf uploads route serves it as a
// download.
func IsInlineContentType(contentType string) bool {
mediaType, _, err := mime.ParseMediaType(contentType)
return err == nil && inlineContentTypes[strings.ToLower(mediaType)]
}
// uploadWriterOptions are the blob writer options of an upload: the content
// type, plus the attachment disposition when the type is not inline.
func uploadWriterOptions(contentType string) *blob.WriterOptions {
opts := &blob.WriterOptions{ContentType: contentType}
if !IsInlineContentType(contentType) {
opts.ContentDisposition = attachmentDisposition
}
return opts
}