fileupload: serve select MIME types as inline
This commit is contained in:
parent
741fd040bb
commit
c1fc2f1e61
|
@ -17,6 +17,27 @@ import (
|
||||||
|
|
||||||
const maxSize = 50 * 1024 * 1024 // 50 MiB
|
const maxSize = 50 * 1024 * 1024 // 50 MiB
|
||||||
|
|
||||||
|
// inlineMIMETypes contains MIME types which are allowed to be displayed inline
|
||||||
|
// by the Web browser. This has security implications: we don't want the
|
||||||
|
// browser to execute any kind of script. For instance, SVG images are
|
||||||
|
// intentionally omitted.
|
||||||
|
var inlineMIMETypes = map[string]bool{
|
||||||
|
"audio/aac": true,
|
||||||
|
"audio/mp4": true,
|
||||||
|
"audio/mpeg": true,
|
||||||
|
"audio/ogg": true,
|
||||||
|
"audio/webm": true,
|
||||||
|
"image/apng": true,
|
||||||
|
"image/gif": true,
|
||||||
|
"image/jpeg": true,
|
||||||
|
"image/png": true,
|
||||||
|
"image/webp": true,
|
||||||
|
"text/plain": true,
|
||||||
|
"video/mp4": true,
|
||||||
|
"video/ogg": true,
|
||||||
|
"video/webm": true,
|
||||||
|
}
|
||||||
|
|
||||||
type Uploader interface {
|
type Uploader interface {
|
||||||
load(filename string) (basename string, modTime time.Time, content io.ReadSeekCloser, err error)
|
load(filename string) (basename string, modTime time.Time, content io.ReadSeekCloser, err error)
|
||||||
store(r io.Reader, username, mimeType, basename string) (outFilename string, err error)
|
store(r io.Reader, username, mimeType, basename string) (outFilename string, err error)
|
||||||
|
@ -78,7 +99,29 @@ func (h *Handler) fetch(resp http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
defer content.Close()
|
defer content.Close()
|
||||||
|
|
||||||
contentDisp := mime.FormatMediaType("attachment", map[string]string{
|
// Guess MIME type from extension, then from content
|
||||||
|
contentType := mime.TypeByExtension(path.Ext(basename))
|
||||||
|
if contentType == "" {
|
||||||
|
var buf [512]byte
|
||||||
|
n, _ := io.ReadFull(content, buf[:])
|
||||||
|
contentType = http.DetectContentType(buf[:n])
|
||||||
|
_, err := content.Seek(0, io.SeekStart) // rewind to output whole file
|
||||||
|
if err != nil {
|
||||||
|
http.Error(resp, "failed to seek file", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if contentType != "" {
|
||||||
|
resp.Header().Set("Content-Type", contentType)
|
||||||
|
}
|
||||||
|
|
||||||
|
contentDispMode := "attachment"
|
||||||
|
mimeType, _, _ := mime.ParseMediaType(contentType)
|
||||||
|
if inlineMIMETypes[mimeType] {
|
||||||
|
contentDispMode = "inline"
|
||||||
|
}
|
||||||
|
contentDisp := mime.FormatMediaType(contentDispMode, map[string]string{
|
||||||
"filename": basename,
|
"filename": basename,
|
||||||
})
|
})
|
||||||
resp.Header().Set("Content-Disposition", contentDisp)
|
resp.Header().Set("Content-Disposition", contentDisp)
|
||||||
|
|
Loading…
Reference in a new issue