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 }